JavaScript provides several mechanisms for handling asynchronous operations, with async
and await
being the most modern and widely used. Let's break them down along with other asynchronous keywords.
1. Async & Await
These keywords allow you to write asynchronous code that looks synchronous, making it easier to read and manage.
Async Function
- Declaring a function as
async
means it always returns a Promise. - Inside an
async
function, you can use theawait
keyword to pause execution until a Promise resolves.
Example:
async function fetchData() {
return "Hello, Async!";
}
fetchData().then(console.log); // Output: "Hello, Async!"
Await Keyword
- The
await
keyword pauses the execution inside anasync
function until the Promise resolves, avoiding the need for.then()
. - Helps keep the code more readable compared to chaining
.then()
callbacks.
Example:
async function fetchData() {
const data = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const json = await data.json();
console.log(json);
}
fetchData();
2. Promises
Before async/await
, JavaScript used Promises for handling asynchronous operations. A Promise represents a value that may be available now, or later, or never.
Example:
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Promise Resolved!"), 2000);
});
myPromise.then(console.log); // Output after 2 seconds: "Promise Resolved!"
3. Callback Functions
Older JavaScript code often relied on callbacks, but they led to "callback hell" when too many nested functions were used.
Example:
function fetchData(callback) {
setTimeout(() => {
callback("Data received!");
}, 2000);
}
fetchData(console.log); // Output after 2 seconds: "Data received!"
This approach became harder to maintain, leading to the rise of Promises and async/await
.
4. Other Asynchronous Keywords
Promise.all()
Runs multiple Promises in parallel and waits for all of them to resolve.
const p1 = Promise.resolve("First");
const p2 = new Promise(resolve => setTimeout(() => resolve("Second"), 1000));
Promise.all([p1, p2]).then(console.log); // ["First", "Second"] after 1 sec
Promise.race()
Resolves as soon as one Promise resolves.
const p1 = new Promise(resolve => setTimeout(() => resolve("First"), 3000));
const p2 = new Promise(resolve => setTimeout(() => resolve("Second"), 1000));
Promise.race([p1, p2]).then(console.log); // Output: "Second" (fastest one wins)
When to Use Each Method?
-
Use
async/await
for cleaner and more readable asynchronous code. - Use Promises when working with APIs and chaining multiple async operations.
-
Use
Promise.all()
for running async tasks in parallel. -
Use
Promise.race()
when only the first resolved result matters.