Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

JavaScript Dictionary

  1. Home
  2. JavaScript Dictionary
  3. async / await

async / await

Since: ES2017(ECMAScript 2017)

A syntax for writing asynchronous code in an intuitive, synchronous style. Use async to declare an asynchronous function and await to wait for a Promise to resolve.

Syntax

// Declares an async function. The return value is automatically wrapped in a Promise.
async function functionName() {
	// Waits for the Promise to resolve.
	var result = await Promise;
}

// Using a function expression
var functionName = async function() {
	var result = await Promise;
};

Keywords

KeywordDescription
asyncPlaced before a function to make it an asynchronous function. An async function always returns a Promise.
awaitWaits for a Promise to resolve and extracts the resulting value. Can only be used inside an async function.

Sample Code

The following samples use a helper function for testing. Please read the promise page first to understand the basics of Promises.

// A helper async function for testing
function wait(ms) {
	return new Promise(function(resolve) {
		setTimeout(function() {
			resolve("Waited " + ms + "ms");
		}, ms);
	});
}

// Basic usage of async/await
async function main() {
	console.log("Start");
	var result = await wait(2000); // Waits for 2 seconds.
	console.log(result); // Logs "Waited 2000ms".
	console.log("Done");
}
main();

// Comparison with the then() chain approach
// then() version
wait(1000).then(function(msg1) {
	console.log(msg1);
	return wait(1000);
}).then(function(msg2) {
	console.log(msg2);
});

// async/await version
async function sequential() {
	var msg1 = await wait(1000);
	console.log(msg1); // Logs "Waited 1000ms".
	var msg2 = await wait(1000);
	console.log(msg2); // Logs "Waited 1000ms" one more second later.
}
sequential();

// Handling errors with try...catch.
async function fetchUserData() {
	try {
		var response = await fetch("https://wp-p.info/sandbox/api.php");
		var data = await response.json();
		console.log(data.name);
	} catch (error) {
		console.log("Failed to fetch data: " + error.message);
	} finally {
		console.log("Network request finished");
	}
}
fetchUserData();

// Running multiple async operations in parallel
async function loadAll() {
	// Combine Promise.all() with await to wait for all operations to finish.
	var results = await Promise.all([
		fetch("https://wp-p.info/sandbox/api.php"),
		fetch("https://wp-p.info/sandbox/api.php")
	]);
	console.log("All data loaded");
}
loadAll();

※ Run the fetch() sample in the browser's developer tools (Console tab).

Start
Waited 2000ms
Done
Waited 1000ms
Waited 1000ms
Waited 1000ms

Return Value of async Functions

An async function always returns a Promise. A value returned with return is automatically wrapped in Promise.resolve(), so the caller can receive it with await or then().

// The return value of an async function is wrapped in Promise.resolve().
async function getGreeting() {
	return "Hello, Iori!";
}

// Since the return value is a Promise, use await to extract it.
async function show() {
	var message = await getGreeting();
	console.log(message); // Prints "Hello, Iori!".
}
show();

// You can also use then().
getGreeting().then(function(msg) {
	console.log(msg); // Prints "Hello, Iori!".
});

// If there is no explicit return, a Promise of undefined is returned.
async function noReturn() {
	console.log("Processing");
}
noReturn().then(function(result) {
	console.log(result); // Prints "undefined".
});

Using await in Loops

Using await inside a for loop executes asynchronous operations one at a time in order. However, this is slow since operations run in series. Use Promise.all() for parallel execution.

// Serial execution: processes one at a time (takes 3 seconds total).
async function serial() {
	var urls = ["/api/users", "/api/posts", "/api/comments"];
	var i;
	for (i = 0; i < urls.length; i++) {
		var response = await fetch(urls[i]);
		console.log("Fetched " + urls[i]);
	}
}

// Parallel execution: starts all at once (takes as long as the slowest one).
async function parallel() {
	var urls = ["/api/users", "/api/posts", "/api/comments"];
	var promises = urls.map(function(url) {
		return fetch(url);
	});
	var responses = await Promise.all(promises);
	console.log("Fetched " + responses.length + " resources");
}

Using await inside forEach() does not wait (because forEach is not an async function). Always use a regular for loop when you need to await sequentially.

NG: await inside forEach does not wait.

async function wrong() {
	var ids = [1, 2, 3];
	ids.forEach(async function(id) {
		var data = await fetch("/api/users/" + id);
		console.log(id); // Order is not guaranteed
	});
	console.log("Done"); // Runs without waiting for forEach's awaits
}

OK: A for loop waits in order.

async function correct() {
	var ids = [1, 2, 3];
	var i;
	for (i = 0; i < ids.length; i++) {
		var data = await fetch("/api/users/" + ids[i]);
		console.log(ids[i]); // Prints 1, 2, 3 in order
	}
	console.log("Done"); // Runs after all iterations complete
}

Common mistake 1: forgetting await

Forgetting await leaves a Promise object in the variable instead of the resolved value.

async function mistake1() {
	var data = fetch("/api/users"); // No await — stores a Promise object
	console.log(data); // Prints "Promise { <pending> }"
}

Correct: Add await to get the response.

async function correct1() {
	var response = await fetch("/api/users");
	var data = await response.json();
	console.log(data); // Prints the JSON response data
}

Common mistake 2: forgetting async

Using await without async causes a SyntaxError.

// Using await in a non-async function causes a SyntaxError
function mistake2() {
	// var result = await fetch("/api"); // SyntaxError
}

// Mistake 3: Not catching errors leads to Unhandled Promise Rejection
async function mistake3() {
	var response = await fetch("https://invalid-url.example.com");
	// A network error occurs, but since it is not caught,
	// an Unhandled Promise Rejection warning appears in the console
}
// mistake3(); // Always wrap in try...catch or append .catch()

Practical Pattern: Loading Indicator

In web applications, a common pattern is to show a loading indicator while fetching data and hide it when done.

<button id="loadBtn">Fetch Data</button>
<p id="loading" style="display: none;">Loading...</p>
<div id="result"></div>
var loadBtn = document.getElementById("loadBtn");
var loading = document.getElementById("loading");
var result = document.getElementById("result");

if (loadBtn && loading && result) {
	loadBtn.addEventListener("click", async function() {
		// Show the loading indicator.
		loading.style.display = "block";
		loadBtn.disabled = true;

		try {
			var response = await fetch("https://wp-p.info/sandbox/api.php");
			var data = await response.json();
			result.textContent = "Fetched: " + JSON.stringify(data);
		} catch (error) {
			result.textContent = "Error: " + error.message;
		} finally {
			// Hide the loading indicator (runs on both success and failure).
			loading.style.display = "none";
			loadBtn.disabled = false;
		}
	});
}

Using a finally block ensures the loading indicator is always hidden, regardless of success or failure. Disabling the button during the request also prevents double submissions.

View sample page

Notes on await

await can only be used inside an async function. Using it in a regular function or at the global scope causes an error.

// Incorrect — causes an error
function normal() {
	var result = await wait(1000); // SyntaxError: await cannot be used outside an async function.
}

// Correct — used inside an async function
async function correct() {
	var result = await wait(1000); // Works as expected.
	console.log(result);
}
correct();

Also, writing multiple await calls sequentially runs them one after another. For independent operations, use Promise.all() to run them in parallel for better performance.

// Sequential execution: takes 3 seconds total.
async function slow() {
	var a = await wait(1000); // Waits 1 second.
	var b = await wait(2000); // Waits another 2 seconds.
	console.log(a, b);
}

// Parallel execution: completes in 2 seconds (the slowest task).
async function fast() {
	var results = await Promise.all([wait(1000), wait(2000)]);
	console.log(results[0], results[1]);
}

Overview

async / await is a syntax introduced in ES2017 for working with Promises more concisely. With Promise chains using then(), the more complex the logic, the harder the code becomes to read. With async / await, you can write asynchronous code that looks just like ordinary synchronous code.

An async function always returns a Promise. When you return a value from inside the function, it is automatically wrapped in Promise.resolve(). If an error is thrown, it is wrapped in Promise.reject(), and the caller can handle it with catch() or try...catch.

async / await is commonly used for asynchronous code. It is an intuitive syntax for tasks that require waiting — such as server communication, database queries, and file I/O.

Browser Compatibility

Chrome Chrome
60+
54 or earlier ×
Firefox Firefox
57+
51 or earlier ×
Safari Safari
18+
10 or earlier ×
Edge Edge
80+
14 or earlier ×
IE IE
11 ×
Not supported in any version
Opera Opera
48+
41 or earlier ×
iOS Safari iOS Safari
18+
10 or earlier ×
Android Browser Android Browser
60+
54 or earlier ×
Chrome Android Chrome Android
60+
54 or earlier ×
Firefox Android Firefox Android
79+
51 or earlier ×

If you find any errors or copyright issues, please .