JavaScript Promise chaining
Imagine you want to:
- Request a user from a server (and wait for the user information).
- Get the user's friends from the server (and wait for the information).
- Show the user name and the user friends' names at the same time.
This is how you do it with a Promise:
// Get the user Jeffrey after waiting 1 second.
const getUser = (resolve) => {
setTimeout(() => resolve({ name: 'Jeffrey' }), 1000);
};
// Get Jeffrey's friends after waiting 2 seconds.
const getFriends = (resolve) => {
setTimeout(() => resolve(['Donny', 'Walter', 'Maude']), 2000);
};
new Promise(getUser) // 1
.then((result) => console.log('User: ' + result.name)) // 2
.then((result) => new Promise(getFriends)) // 3
.then((result) => console.log('Friends: ' + result)); // 4
// result:
// User: Jeffrey
// Friends: Donny, Walter, Maude
What is going on?
- The Promise is created and it does a request to get the user.
- Then, after waiting 2 seconds, it outputs "User: Jeffrey"
- Then, it requests Jeffrey's friends names.
- Then, it outputs Jeffrey's friends names.
You see the then
methods called one after the other? That is chaining!
Although the example is fake, this need of getting something based on a first request happens a lot.
Notice that:
- We don't need to store the promise in a variable. We can call the
then
method right after the Promise creation (point 1). - You can pass whatever you wish to a resolve or reject function (e.g. array, object, error objects).
Example of implementing wait with a Promise
If you used a lot of callbacks before, you are probably already convinced about Promises. If not, let's see how we can create a wait
function:
const wait = (ms) => new Promise((res) => setTimeout(res, ms));
wait(2000)
.then(() => console.log('hey'))
.then(() => wait(1000))
.then(() => console.log('ho'));
How cool is that?! The code is written almost like synchronous code!
Notice that after a Promise calls the resolve
or reject
function, the promise state won't change again. That is why a new Promise needs to be created every time we call the wait
function.
We'll talk about other Promise rules later.
Questions
What's the output?
const w = (ms) => new Promise((res) => setTimeout(() => res(), ms));
const f1 = () => console.log(1);
w(2000).then(f1);
What's the output?
const f = (ms) => new Promise((res) => setTimeout(res, ms));
f(1000)
.then(() => console.log('hi'))
.then(() => f(2000))
.then(() => console.log('there'));