Promise Class Methods
In some tasks you need to deal with a whole set of promises. In one case, you have to wait for all of them to be completed and only then to process their result, and in other cases, it is enough to wait for the execution of any, ignoring the rest, etc. It is for these cases that the Promise
class has static methods for handling one or a group of promises.
Promise.all()
Takes an array of promises, waits for them to execute and returns a promise. If all promises are successful, the returned promise will go into the fulfilled
state, and its value will be an array of the results of each promise. If at least one of the promises is rejected, the returned promise will go into the rejected
state, and its value will be an error.
Promise.all([promise1, promise2, promise3, ...])
Let's write a function that takes text for resolve()
and a delay in milliseconds, and returns a promise as its result. Then, let's create two promises with different delay times.
const makePromise = (text, delay) => {
return new Promise(resolve => {
setTimeout(() => resolve(text), delay);
});
};
const promiseA = makePromise("promiseA value", 1000);
const promiseB = makePromise("promiseB value", 3000);
Promise.all([promiseA, promiseB])
.then(value => console.log(value)) //["promiseA value", "promiseB value"]
.catch(error => console.log(error));
The callback of then()
will be called after three seconds, that is, after the promiseB
promise has been executed. As for the promiseA
promise, it will be executed after one second and will just wait. If any of the promises is rejected, it will call the catch()
method’s callback.
Promise.race()
Returns a fulfilled or rejected promise, depending on the result of the “fastest” of all the promises passed, with a value or reason for rejection.
Promise.race([promise1, promise2, promise3, ...])
When at least one promise from the array is fulfilled or rejected, the returned promise will go into the resolved
or rejected
state, and all the rest will be discarded.
const makePromise = (text, delay) => {
return new Promise(resolve => {
setTimeout(() => resolve(text), delay);
});
};
const promiseA = makePromise("promiseA value", 1000);
const promiseB = makePromise("promiseB value", 3000);
Promise.race([promiseA, promiseB])
.then(value => console.log(value)) // "promiseA value"
.catch(error => console.log(error));
In a second, when promiseA
is fulfilled, the callback of the then()
or catch()
method will be called. The second promise, promiseB
, will be ignored.
Promise.resolve()
and Promise.reject()
These are static methods for creating instantly fulfilled or rejected promises. They function in the same way as new Promise()
except that you can specify a delay, with a shorter syntax.
// Fulfilled promise
new Promise(resolve => resolve("success value")).then(value =>
console.log(value)
);
Promise.resolve("success value").then(value => console.log(value));
// Rejected promise
new Promise((resolve, reject) => reject("error")).catch(error =>
console.error(error)
);
Promise.reject("error").catch(error => console.error(error));
These methods are used when promisifying functions, if you need to build a chain of promises and have the initial value. Let's refactor the following code.
const makeGreeting = guestName => {
if (guestName === "" || guestName === undefined) {
return {
success: false,
message: "Guest name must not be empty",
};
}
return {
success: true,
message: `Welcome ${guestName}`,
};
};
const result = makeGreeting("Mango");
if (result.success) {
console.log(result.message);
} else {
console.error(result.message);
}
When using callbacks, there is no need to return complex objects with the status of operation and check it in outer code.
const makeGreeting = (guestName, onSuccess, onError) => {
if (guestName === "" || guestName === undefined) {
return onError("Guest name must not be empty");
}
onSuccess(`Welcome ${guestName}`);
};
makeGreeting(
"Mango",
greeting => console.log(greeting),
error => console.error(error)
);
The last step is to promisify the makeGreeting()
function in order to make it completely independent of outer code.
const makeGreeting = guestName => {
if (guestName === "" || guestName === undefined) {
return Promise.reject("Guest name must not be empty");
}
return Promise.resolve(`Welcome ${guestName}`);
};
makeGreeting("Mango")
.then(greeting => console.log(greeting))
.catch(error => console.error(error));