Understanding ES6 Promises and the async nature of Javascript

In this example we are taking a closer look at the asynchronous nature of Javascript and ES6’s Promises.
Promises were not natively available in the previous version of Javascript, in ES5, only through certain implementations, libraries such as Bluebird or Kris Kowal’s Q.
Before promises, the only native way of handling asynchronous events were callback functions, which in more complicated cases resulted in a nested pyramid of callbacks (“callback hell”), a code that is hard to read and less composable.

Let’s take a look at the code above.
We created two functions, myPromiseCreator() and handleMyPromise().

Creating the Promise

The myPromiseCreator() function creates, and returns a Promise object. To create a Promise object, we need to pass a callback function as an argument to the constructor of the Promise object:

new Promise( (resolve,reject) =>
// The body of the arrow function. Do some async stuff here, and return the result
)

Notice that we are using ES6’s new arrow function shorthand for declaring our function that we are passing in to the Promise object constructor as an argument.
Our promise object‘s constructor receives a callback function as an argument, which in turn takes two arguments, resolve and reject, which are both callback functions as well.
Inside our function we set a conditional case which detects if the async event (in our case a setTimeout() function) took more than 3 seconds.
If our async operation took more than 3 seconds, we reject the promise, otherwise we resolve it. Notice, that instead of a return statement, we return value from our Promise with the resolve or reject statements.

Handling the Promise

Our handleMyPromise() function is responsible for handling our Promise.
It initiates the creation of the Promise object (and starts the async process) by calling the myPromiseCreator(), and calls the Promise‘s built-in then() function on the Promise object returned by our myPromiseCreator(), which handles the case of a resolved Promise (a success).
We also call the Promise‘s built-in catch() function on our returned Promise object, which handles the case of a rejected Promise (a failure of the async operation). Remember, that we created the logic in the myPromiseCreator() function to reject or resolve our Promise.

So this is our logic to handle our returned Promise, but there is still an important part within our handleMyPromise() function after(!) our Promise handling logic at line:18: document.write('Single thread continued before our Promise returned!');
This is important to demonstrate the single-threaded and asynchronous nature of Javascript. If you check the “Result” tab, you will see that our first message in the document is 'Single thread continued before promise resolved!'.
So Javascript continues the execution of our code after we trigger our async processes (we trigger it by calling the handleMyPromise() function in the last 4 lines of our code).

So how can Javascript be single threaded and asynchronous at the same time?

Well, actually Javascript itself is not asynchronous.
Every asynchronous event available in Javascript is actually happening “outside” Javascript code execution, through built-in browser functionalities, available to Javascript through the browser’s web APIs.
Further in-depth information regarding the single threaded and asynchronous nature of Javascript: The event loop, and how is Javascript asynchronous and single threaded at the same time?

Author: Nandor Persanyi

Leave a Reply

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