Javascript Promises are not difficult. However, lots of people find it a little bit hard to understand at the beginning.
There are a lot of definition of promise
A promise has 3 states:
Simply put, a promise is an object that holds a value that is promised to be given to you at some point in time. One can retrieve the value a promise is holding by calling the promises then
method. A promise starts out in the pending state, then on success it will be in the fulfilled state, or if an error occurs, it will be in the rejected state.
Promise syntax look like this
new Promise(function (resolve, reject) { ... } );
or in visualization form
Let's look at Promise in real world example.
Imagine you are a kid. Your mom promises you that she'll get you a new phone next week. You don't know if you will get that phone until next week. Your mom can either really buy you a brand new phone, or stand you up and withhold the phone if she is not happy.
That is a promise. A promise has 3 states. They are:
Let's convert this to JavaScript. Example in ES5
var isMomHappy = false; // Promise var willIGetNewPhone = new Promise( function (resolve, reject) { if (isMomHappy) { var phone = { brand: 'Samsung', color: 'black' }; resolve(phone); // fulfilled } else { var reason = new Error('mom is not happy'); reject(reason); // reject } } );
What you need to remember is, when the result is successful, call resolve(your_success_value)
, if the result fails, call reject(your_fail_value)
in your promise. In our example, if mom is happy, we will get a phone. Therefore, we call resolve
function with phone
variable. If mom is not happy, we will call reject
function with a reason reject(reason)
.
Now that we have the promise, let's consume it.
willIGetNewPhone .then(function (fulfilled) { // you got a new phone console.log(fulfilled); }) .catch(function (error) { // mom don't buy it console.log(error.message); });
Example in ES6
const isMomHappy = true; // Promise const willIGetNewPhone = new Promise( (resolve, reject) => { if (isMomHappy) { const phone = { brand: 'Samsung', color: 'black' }; resolve(phone); } else { const reason = new Error('mom is not happy'); reject(reason); } } ); willIGetNewPhone .then(fulfilled => console.log(fulfilled)) .catch(error => console.log(error.message));
Notes that all the var
are replaced with const
. All the function(resolve, reject)
has been simplified to (resolve, reject) =>
.
This is an another example of invoking a Promise-based function waitForIt()
function waitForIt(n) { return new Promise((resolve, reject) => { setTimeout(() => resolve('DONE'), n); }); } waitForIt(5) .then(x => console.log('Result: ' + x)) .catch(error => console.log('There has been a horrible mistake!', error); })
Promises are chainable
Let's say, you, the kid, promise your friend that you will show them the new phone when your mom buy you one.
That is another promise. Let's write it!
var showOff = function (phone) { return new Promise( function (resolve, reject) { var message = 'Hey friend, I have a new ' + phone.color + ' ' + phone.brand + ' phone'; resolve(message); } ); };
Notes:
reject
. It's optional.Promise.resolve
instead.var showOff = function (phone) { var message = 'Hey friend, I have a new ' + phone.color + ' ' + phone.brand + ' phone'; return Promise.resolve(message); };
Let's chain the promises. You, the kid can only start the showOff
promise after the willIGetNewPhone
promise.
willIGetNewPhone .then(showOff) .then(function (fulfilled) { console.log(fulfilled); // output: 'Hey friend, I have a new black Samsung phone.' }) .catch(function (error) { // oops, mom don't buy it console.log(error.message); // output: 'mom is not happy' });
Takeaways
Useful links