Javascript Promises

Özgün Bal

Contents

  • What is Promise?
  • Callback vs Promise
  • Syntax
  • Chaining Promises
  • Promise methods
  • Async/Await (ES7)

Simple Analogy of Promises

Simple Analogy of Promises

Callbacks

  • A function for future call
  • Causes callback hell
  • Can be called too early
  • Can be not called
  • Can be called few or many times
  • Fail to pass along any necessary parameters
  • Swallow error/exceptions

Promises

  • Native type for future value
  • More structured way to handle asynchronous jobs

Solves these

Callback Hell

Downsides of callbacks

// Company A's API that you're using in your application
function untrustedAPIMethod (paramX, paramY, callback) {
  // 1 - If it is not actually asynchronous, may called too early
  callback();
  
  // 2- Callback is not called at all due to buggy implementation
  
  // 3- Can be called more than needed
  for(let i=0; i< task.length; i++) {
    callback();
  }
  
  // 4- Fail to pass parameters
  callback();
  // or
  callback(null); // instead of error first callback: callback(null, result)
  
  // 5- Swallow errors
  const result = `I\'m not an arry type but .map() method 
     is belong to Array.prototype`.map(letter => console.log(letter))
  // Before callback, TypeError is throwed and and callback never called
  callback(result);
}

Promise syntax

  • Called with new to create one
  • Takes a function with two parameters
  • One for fulfillment, one for rejection of the desired task
  • Return a Promise object immediately
  • Not mutated, resolved once
  • Acquiring the value is done by .then()
const promise = new Promise(function(resolve, reject){
  if (satisfiedCondition) {
    resolve('Task is done');
  } else {
    reject('Error occured');
  }
})

promise.then(function(data){
  console.log(data) // prints 'Task is done' when promise is resolved
}).catch(function(error){
  console.log(error) // prints 'Error occured' when promise is rejected
})

Promise advantages

  • Can be called only once
  • resolve() and reject() takes only one parameter
  • Unhandled errors cause rejection
  • Always asynchronous even with immediately resolved ones

Can I use Promises?

Chaining Promises

asyncFunc()
  .then(result => {
    return anotherAsyncFunc(result);
  })
  .then(chainResult => {
    return chainResult.json();
  })
  .catch(error => {
  console.log(error);
  })

DEMO

Promise methods

  • Promise.resolve()
  • Promise.reject()
  • Promise.all()
  • Promise.race()
// Immediately resolved promise object
const resolved = Promise.resolve(5);

// Immediately rejected promise object
const rejected = Promise.reject('Oops');

// Takes array of promises and resolves if all of them resolved otherwise rejects
const allFulfilled = Promise.all([resolved, rejected]);

// Returns first resolved/rejected promise in array of promises
const raceOfPromises = Promise.race(promiseArray)

DEMO

Async/Await

  • Better code
  • More readable
  • Uses new words: async and await
  • ES7 feature
const makeRequest = async () => {
  const value1 = await promise1()
  const value2 = await promise2(value1)
  return promise3(value1, value2)
}
const value;
promise1()
  .then(value1 => {
    value = value1
    return promise2(value1);
  })
  .then(value2 =>{
    return promise3(value, value2);
})

DEMO

Can I use Async/Await?

Useful Resources

  • You Don't Know Javascript: Async & Performance
    • https://github.com/getify/You-Dont-Know-JS
  • Udacity - Javascript Promises
    • https://www.udacity.com/course/javascript-promises--ud898

Thank you for listening