Understanding JavaScript promise object
Summary:
A promise in Javascript is an object which represent the eventual completion or failure of an asynchronous operation. Promises represent a proxy for a value which are getting in some point in the future.
A promise can have 3 states which are the following:
- Pending: This is the initial state of the promise, the promise is now waiting for either to be resolved or rejected. For example, when are reaching out to the web with an AJAX request and wrapping the request in a promise. Then the promise will be pending in the time window in which the request is not returned.
- Fulfilled: When the operation is completed succesfully, the promise is fulfilled. For example, when we are reaching out to be web using AJAX for some JSON data and wrapping it in a promise. When we are succesfully getting data back the promise is said to be fulfilled.
- Rejected: When the operation has failed, the promise is rejected. For example, when we are reaching out to be web using AJAX for some JSON data and wrapping it in a promise. When we are getting a 404 error the promise has been rejected.
Promise Constructor:
We can create a promise in the following manner:
let prom = new Promise((res, rej) => {
console.log('synchronously executed');
if (Math.random() > 0.5) {
res('Success');
} else {
rej('Error');
}
})
prom.then((val) => {
console.log('asynchronously executed: ' + val);
}).catch((err) => {
console.log('asynchronously executed: ' + err);
}).finally(() => {
console.log('promise done executing');
});
console.log('last log');
Points of interest:
- The code inside the promise constructor is synchronously executed.
then
method takes as a first argument a callback which is asynchronously executed on promise fulfillment.then
method takes as a second argument a callback which is asynchronously executed on promise rejection. However we are usually using thecatch
method for this (because this is more verbose), which also takes a callback which is asynchronously executed on promise rejection.catch
is essentially the same asthen(null, failCallback)
.- The
then
callback receives as a first argument the resolved value (the string 'success' in this case). - The
catch
callback receives as a first argument the rejected value (the string 'Error' in this case). - The
finally
method receives a callback which is executed on both promise fulfillment and rejection. Here we can write 'cleanup' code which need to be executed always regardless of promise outcome.
Your example:
In your code 'Zami' was printed before 'there' because the log which logged 'there' was in a then
callback function. We earlier pointed out that these callbacks are executed asynchronously and thus will be executed last.
I would recommend you to understand how event loop works in JavaScript.
take time and watch this Video.
It will clear you doubts.
Even though you resolved the promised synchronously, the handlers you pass into then
get called asynchronously. This is according to the defined specification:
onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack
Promise execution is asynchronous, which means that it's executed, but the program won't wait until it's finished to continue with the rest of the code.
Basically, your code is doing the following:
- Log 'Hi'
- Create a promise
- Execute the promise
- Log 'zami'
- Promise is resolved and logs 'There'.
If you want it to print 'Hi there, zami', you will have to
myPromise.then(function (result) {
// Resolve callback.
console.log(result);
console.log('zami');
}, function (result) {
// Reject callback.
console.error(result);
});