JavaScript Promises
Promises are the foundation of asynchronous JavaScript. Understanding them deeply is essential for modern web development.Promise Basics
- Promises start in a pending state, neither fulfilled or rejected
- When the operation is completed, a promise will become fulfilled with a value
- If the operation fails, a promise will get rejected with an error
Creating Promises
The function passed to thePromise constructor will execute synchronously.
From Values
From Async Operations
Handling Promises
Promise.prototype.then()
Promise.prototype.then() accepts two optional arguments (onFulfilled, onRejected):
- Calls
onFulfilledonce the promise is fulfilled - Calls
onRejectedif the promise is rejected - Passes errors through if
onRejectedis undefined
Promise.prototype.catch()
Promise.prototype.catch() accepts one argument (onRejected):
- Behaves like
Promise.prototype.then()whenonFulfilledis omitted - Passes fulfilled values through
Promise.prototype.finally()
Promise.prototype.finally() accepts one argument (onFinally):
- Calls
onFinallywith no arguments once any outcome is available - Passes through input promise
All three methods will not be executed at least until the next tick, even for promises that already have an outcome.
Combining Promises
Promise.all()
Turns an array of promises into a promise of an array:Promise.race()
Passes through the first settled promise:Promise.allSettled()
Waits for all promises to settle (fulfilled or rejected):async/await
The modern way to work with promises.Basic Usage
Key Points
- Calling an
asyncfunction always results in a promise (async () => value)()will resolve tovalue(async () => throw err)()will reject with an errorawaitwaits for a promise to be fulfilled and returns its valueawaitcan only be used inasyncfunctionsawaitalso accepts non-promise valuesawaitalways waits at least until the next tick before resolving
Practical Example
Running Promises in Series
JavaScript promises are asynchronous, meaning they execute in parallel. To execute promises one after another (sequentially), chain them usingArray.prototype.reduce():
Promise.prototype.then().
Common Patterns
Timeout with Promise.race()
Retry Logic
Parallel with Limit
Best Practices
Always handle errors
Always handle errors
Use
.catch() or try/catch with async/await to handle errors. Unhandled promise rejections can cause issues.Prefer async/await over .then()
Prefer async/await over .then()
async/await is more readable and easier to debug. Use .then() for simple chains.
Don't forget to await
Don't forget to await
A common mistake is forgetting to await async functions, which returns a promise instead of the value.
Use Promise.all() for parallel operations
Use Promise.all() for parallel operations
When operations don’t depend on each other, run them in parallel with Promise.all() for better performance.