- Understand what promises are
- Define A Promise
A Promise in short:
"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 :(.
In the simplest sense, A promise represents the eventual result of an asynchronous operation. It is a placeholder into which the successful result value or reason for failure will materialize.
That is a promise. A promise has 3 states. They are:
Promise is pending: You don't know if you will get that phone until next week. Promise is resolved: Your mom really buy you a brand new phone. Promise is rejected: You don't get a new phone because your mom is not happy.
- Below let's see what a simple promise might look like
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
}
}
);
- Let's step through this code
- We have a boolean
isMomHappy
, to define if mom is happy. - We have a promise
willIGetNewPhone
. The promise can be eitherresolved
(if mom get you a new phone) orrejected
(mom is not happy, she doesn't buy you one). - There is a standard syntax to define a new Promise, refer to MDN documentation, a promise syntax look like this.
// promise syntax look like this
new Promise(/* executor*/ function (resolve, reject) { ... } );
- What you need to remember is, when the result is successful, call
resolve(your_success_value)
, if the result fails, callreject(your_fail_value)
in your promise. - In the example above, 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)
;
- So above, we have a promise. now let's see how we could "consume" a promise
var askMom = function () {
willIGetNewPhone
.then(function (fulfilled) {
// yay, you got a new phone
console.log(fulfilled);
// output: { brand: 'Samsung', color: 'black' }
})
.catch(function (error) {
// oops, mom don't buy it
console.log(error.message);
// output: 'mom is not happy'
});
};
askMom();
- We have a function called
askMom
. In this function, we will consume our promisewillIGetNewPhone
. - We want to take some action once the promise is resolved or rejected, we use
.then
(for success) and.catch
(for error) to handle our action. - In our example, we have
function(fulfilled) { ... }
in.then
. What is the value of fulfilled? The fulfilled value is exactly the value you pass in your promiseresolve(your_success_value)
. Therefore, it will be phone in our case. - We have
function(error){ ... }
in.catch
. What is the value of error? As you can guess, the error value is exactly the value you pass in your promisereject(your_fail_value)
. Therefore, it will be reason in our case.
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.
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);
}
);
};
- In this example, you might realize we didn't call the reject. It's optional.
- We can shorten this sample like using Promise.resolve instead.
//shortened
var showOff = function (phone) {
var message = 'Hey friend, I have a new ' +
phone.color + ' ' + phone.brand + ' phone';
return Promise.resolve(message);
};
call the promise
var askMom = function () {
willIGetNewPhone
.then(showOff) // chain it here
.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'
});
};
- Promises are asynchronous. Let's log a message before and after we call the promise.
var askMom = function () {
console.log('before asking Mom'); // log before
willIGetNewPhone
.then(showOff)
.then(function (fulfilled) {
console.log(fulfilled);
})
.catch(function (error) {
console.log(error.message);
});
console.log('after asking mom'); // log after
}
The sequence we expect is probably something like
/*
1. before asking Mom
2. Hey friend, I have a new black Samsung phone.
3. after asking mom
*/
but the actual sequence is
/*
1. before asking Mom
2. after asking mom
3. Hey friend, I have a new black Samsung phone.
*/
Why? Because life (or JS) waits for no man.
You, the kid, wouldn't stop playing while waiting for your mom promise (the new phone). Don't you? That's something we call asynchronous, the code will run without blocking or waiting for the result. Anything that need to wait for promise to proceed, you put that in .then
.
- what is a promise?
- what is one of the 3 promise states?
Lets take a look at our callback code, and see what it looks like wrapped as promises