Categories
Modern JavaScript

Best of Modern JavaScript — Promises

Spread the love

Since 2015, JavaScript has improved immensely.

It’s much more pleasant to use it now than ever.

In this article, we’ll look at JavaScript promises.

Benefits of Promises

Promises are chained.

And they look similar to synchronous code.

For example, we can write:

asyncFunction(arg)  
  .then(result1 => {  
    console.log(result1);  
    return asyncFunction2(x, y);  
  })  
  .then(result2 => {  
    console.log(result2);  
  });

We return a promise in the then callback to let us call then again.

Chaining is also simple since we just call then until we’re done with running the promises we want.

Composing async calls is easier since we can do the chaining.

Error handling can be done with the catch method.

For instance, we can write:

asyncFunction(arg)  
  .then(result1 => {  
    console.log(result1);  
    return asyncFunction2(x, y);  
  })  
  .then(result2 => {  
    console.log(result2);  
  })  
  .catch(error => {  
    console.log(error);  
  })

The catch method takes a callback that has an error parameter.

So we can do whatever we want with them inside the callback.

The function signatures are clear and we can see the parameters easily.

Promises is also a standard way to write async code.

Before promises are introduced to ES6 as a native features, there’re many libraries that implement the same thing.

But now, ES6 makes promises standard so we can use it anywhere.

Creating Promises

To create a promise, we can use the Promise constructor.

For instance, we can write:

new Promise((resolve, reject) => {  
  setTimeout(() => resolve('DONE'), 100);  
});

We use the constructor with a function that takes the resolve and reject parameters.

resolve is a function that’s called to return the value when it succeeds.

reject is a function that’s called to return the reason why the promise fails.

A promise is a container for value and an event emitter.

Promises looks like synchronous code, but they’re non-blocking.

They can’t return anything synchronously.

ES6 introduced a way for us to suspend and resume code with generators.

Therefore, this is used as the foundation for promises and async functions in JavaScript.

For instance, if we have:”

async function main() {  
  const x = await asyncFunc();  
  console.log(x);  
  //...  
}  
main();

asyncFunc returns a promise and runs the console log after the function is called.

await is like yield in JavaScript generator functions.

It does the same thing. It pauses the code and then continues running when the result is retrieved.

Using Promises

Promises have 3 states.

They can be pending, fulfilled, or rejected.

Pending means that the result hasn’t been computed.

Fulfilled means the result was computed successfully.

Rejected means a failure occurred during computation.

The parameter we pass into the Promise constructor is called an executor.

In addition to calling reject to make a promise fail, we can also reject a promise with an exception.

Consuming a Promise

To consume a promise, we can call then to get the resolved result from a promise.

The callback we pass into then takes the resolved results of a promise.

catch takes a callback which takes the argument we passed into reject .

For example, we can write:

promise  
  .then(value => {  
    //...  
  })  
  .catch(error => {  
    //...  
  });

value has the resolved value of promise .

error has the rejected value.

then can also take 2 arguments.

One is the resolved callback and the 2nd argument is the rejected callback.

So we can also catch errors by writing:

promise.then(  
  null,  
  error => {  
    //...  
  });

The 2nd argument is the same as the catch callback and catches the error of the promise.

Conclusion

Promises have many benefits, and we can create and consume them in a standard way.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *