Promises represent a value that may be available now, later, or never. Async/Await is modern syntax that makes working with promises easier.
JavaScript Promises & Async/Await
1) Creating a Promise
A promise is created with new Promise() and either resolves or rejects.
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve('done'), 1000);
});
2) then / catch / finally
Handle resolved values with then, errors with catch, and cleanup with finally.
p
.then(res => console.log(res))
.catch(err => console.error(err))
.finally(() => console.log('Always runs'));
3) Promise Chaining
Each then returns a new promise, allowing sequential async steps.
const chain = Promise.resolve(2);
chain
.then(n => n * 2)
.then(n => n + 1)
.then(res => console.log(res)); // 5
4) Promise.all & Promise.race
Promise.all waits for all promises; Promise.race resolves/rejects with the first one.
const p1 = Promise.resolve('A');
const p2 = Promise.resolve('B');
Promise.all([p1, p2]).then(res => console.log(res));
Promise.race([p1, p2]).then(res => console.log(res));
5) Async / Await
Async functions return promises. await pauses until a promise resolves.
async function fetchData() {
const res = await Promise.resolve('Data loaded');
console.log(res);
}
fetchData();
6) Error Handling in Async Functions
Wrap await calls in try...catch for errors.
async function run() {
try {
const res = await Promise.reject('Oops!');
console.log(res);
} catch(e) {
console.error(e);
}
}
run();
Tip: Use
async/await for readability, but remember it’s still promises under the hood. For parallel async tasks, use Promise.all.