Async and await make asynchronous JavaScript easier to read and understand. They allow you to write Promise-based code in a style that looks similar to ordinary sequential code.
The async keyword is used before a function declaration
to make the function asynchronous. An async function always returns
a Promise.
async function greet() {
return "Hello Student";
}
greet().then(function(message) {
console.log(message);
});
Hello Student
greet() returns a Promise that fulfills with
the value "Hello Student".
The await keyword waits for a Promise to settle.
If the Promise fulfills, await produces its result. If it rejects,
await throws an error that can be handled using
try...catch.
function getMessage() {
return new Promise(function(resolve) {
resolve("Welcome to Node.js");
});
}
async function showMessage() {
const message = await getMessage();
console.log(message);
}
showMessage();
Welcome to Node.js
The await keyword waits for the Promise returned
by getMessage() to fulfill before assigning
its result to message.
We can use a Promise with setTimeout() to demonstrate
asynchronous operations that take some time.
function waitTwoSeconds() {
return new Promise(function(resolve) {
setTimeout(function() {
resolve("Two seconds completed!");
}, 2000);
});
}
async function start() {
console.log("Please wait...");
const result = await waitTwoSeconds();
console.log(result);
}
start();
Please wait...
Two seconds completed!
start()
function at that point, but it does not block the entire
Node.js event loop.
An async function can accept parameters and return calculated values. Its returned value is delivered through a Promise.
async function add(a, b) {
return a + b;
}
async function calculate() {
const result = await add(10, 20);
console.log("Sum:", result);
}
calculate();
Sum: 30
Sometimes a Promise rejects because an operation fails.
Use try...catch inside an async function to handle
errors produced by an awaited Promise.
function checkNumber() {
return new Promise(function(resolve, reject) {
reject(new Error("Something went wrong!"));
});
}
async function check() {
try {
const result = await checkNumber();
console.log(result);
} catch (error) {
console.log("Error:", error.message);
}
}
check();
Error: Something went wrong!
The rejected Promise throws an error at the await expression.
The catch block handles that error.
The finally block runs after the try/catch process,
whether the operation succeeds or fails.
async function processData() {
try {
console.log("Processing data...");
throw new Error("Processing failed");
} catch (error) {
console.log(error.message);
} finally {
console.log("Process finished");
}
}
processData();
Processing data...
Processing failed
Process finished
When two asynchronous operations are independent, you can run them
concurrently using Promise.all() instead of waiting
for each one sequentially.
function task(name, delay) {
return new Promise(function(resolve) {
setTimeout(function() {
console.log(name);
resolve();
}, delay);
});
}
async function runTasks() {
await task("Task 1", 1000);
await task("Task 2", 1000);
console.log("All tasks completed");
}
runTasks();
Task 1
Task 2
All tasks completed
The second task starts only after the first task completes. The total waiting time is approximately two seconds.
function task(name, delay) {
return new Promise(function(resolve) {
setTimeout(function() {
console.log(name);
resolve(name);
}, delay);
});
}
async function runTasks() {
const results = await Promise.all([
task("Task 1", 1000),
task("Task 2", 1000)
]);
console.log("All tasks completed");
console.log(results);
}
runTasks();
Task 1
Task 2
All tasks completed
[ 'Task 1', 'Task 2' ]
Promise.all() preserves input order in its
results array, even if the tasks finish in a different order.
Async and await are commonly used to fetch data from APIs.
The following example uses the built-in Node.js
fetch() function available in modern Node.js versions.
async function getUser() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users/1"
);
if (!response.ok) {
throw new Error("HTTP error: " + response.status);
}
const user = await response.json();
console.log("Name:", user.name);
console.log("Email:", user.email);
} catch (error) {
console.log("Failed to fetch user:", error.message);
}
}
getUser();
This example requires an internet connection. It sends an HTTP request, checks the response status, converts the response body to JSON, and handles possible errors.
response.ok when you want
to treat HTTP error statuses as errors.
| Rule | Explanation |
|---|---|
async |
Makes a function return a Promise. |
await |
Waits for a Promise to settle inside an async function. |
try...catch |
Handles errors from awaited operations. |
finally |
Runs after the try/catch process. |
Promise.all() |
Waits for multiple Promises and returns their results. |
| Top-level await | Supported in ES modules in modern Node.js. CommonJS files should use await inside an async function. |
Select the correct answer for each question.