JavaScript Promises
Imagine asking someone to marry you. Their answer is a promise.
A JavaScript promise also represents an answer that may not be ready yet, and it can end up in one of three states:
- pending: the promise is waiting to settle ⏳
- fulfilled: the promise completed successfully 😊
- rejected: the promise failed 🥲
When you wait for a promise, you usually keep doing other work until the result is ready. That is the whole point: promises let your code handle results later without blocking the rest of the program.
Creating a promise
If you already know the result, you can create a settled promise immediately.
Use Promise.resolve() for a fulfilled promise and Promise.reject() for a rejected one.
const password = Promise.resolve("123");
const authenticated = Promise.reject(new Error("Log in to continue")); You can also create a promise that settles later using new Promise(...).
The constructor takes a function with two parameters: resolve and reject.
function propose() {
if (Math.random() < 0.5) {
console.log('She said no');
return Promise.reject(new Error("You're not lucky today 😪"));
}
console.log('She said yes');
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
return reject(new Error('You cheated on me 🥹'));
}
resolve('Wow! Finally, we are married 👰');
}, 2000);
});
} This example shows a promise that may reject immediately, or wait 2 seconds and then either reject or resolve.
Using promises
To handle a promise result, use .then() for success and .catch() for errors.
password.then(value => {
console.log(value);
});
authenticated.catch(err => {
console.error(err);
});
propose()
.then((fulfilled) => {
console.log(fulfilled);
})
.catch((rejected) => {
console.error(rejected);
}); Async / await
async / await is a cleaner syntax for working with promises.
Here is the same propose example written with async/await:
async function propose() {
if (Math.random() < 0.5) {
console.log('She said no');
throw new Error("You're not lucky today 😪");
}
console.log('She said yes');
await delay(2000);
if (Math.random() < 0.5) {
throw new Error('You cheated on me 🥹');
}
return 'Wow! Finally, we are married 👰';
}
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
} Then use try / catch to receive the result and handle any errors:
try {
const result = await propose();
console.log(result);
} catch (error) {
console.error(error.message);
} Note that
awaitcan only be used inside anasyncfunction. If you want to use it at the top level, you can wrap it in an immediately invoked async function. But in modern JavaScript environments, you can useawaitat the top level without needing to wrap it in an async function.Note also that
awaitwill pause the execution of the async function until the promise settles, but it does not block the entire program.
Here are more resources to learn about promises: