← Back to JavaScript series
πŸŒ€
Async
Intermediate Β· Prerequisite: 15_Promise

16. async / await

Adding the `async` keyword wraps a function's return value in a Promise automatically.

asyncawaitasyncerror handling
Duration
⏱ ~1.5 hours
Level
πŸ“Š Intermediate
Prerequisite
🎯 Lecture 15
OUTCOME
Adding the `async` keyword wraps a function's return value in a Promise automatically.

What you'll learn

  • 1Know that an `async` function always returns a Promise.
  • 2Use `await` to read a Promise's value as if it were synchronous.
  • 3Handle async errors with `try/catch`.
  • 4Distinguish parallel from sequential execution.
  • 5Combine `Promise.all` with `await` for efficient parallel work.

Overview

Adding the `async` keyword wraps a function's return value in a Promise automatically.

Core Concepts

1. async functions

Adding the `async` keyword wraps a function's return value in a Promise automatically.

javascript
async function f() {
  return 42;
}
f().then((v) => console.log(v)); // 42

2. await

`await` pauses the function until the Promise settles. You can only use it inside an `async` function (except top-level await in modules).

javascript
async function main() {
  const value = await Promise.resolve(10);
  console.log(value); // 10
}

3. try / catch

Use try/catch to handle async errors.

javascript
async function load() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

4. Parallel vs sequential

Back-to-back `await`s wait for each previous task to finish, which is slow. Run independent tasks in parallel with `Promise.all`.

javascript
// slow (sequential)
const a = await fetchA();
const b = await fetchB();

// fast (parallel)
const [a, b] = await Promise.all([fetchA(), fetchB()]);

Examples

FileWhat it covers
01_async_basic.jsBasics of async functions and await
02_try_catch.jsError handling with try/catch
03_promise_all.jsawait + Promise.all
04_parallel.jsParallel vs sequential timing

src/01_async_basic.js

javascript
/**
 * Basics of async/await.
 */
function delay(ms, value) {
  return new Promise((resolve) => setTimeout(() => resolve(value), ms));
}

async function main() {
  console.log("start");
  const value = await delay(200, "hello!");
  console.log("got:", value);
  console.log("end");
}

main();

src/02_try_catch.js

javascript
/**
 * Handle async errors with try/catch.
 */
function fetchData(ok) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (ok) resolve({ id: 1 });
      else reject(new Error("network failed"));
    }, 100);
  });
}

async function run() {
  try {
    const data = await fetchData(false);
    console.log("ok:", data);
  } catch (err) {
    console.error("error:", err.message);
  } finally {
    console.log("cleanup");
  }
}

run();

src/03_promise_all.js

javascript
/**
 * Combine await with Promise.all for parallel results.
 */
function fetchValue(label, ms) {
  return new Promise((resolve) => setTimeout(() => resolve(label), ms));
}

async function loadAll() {
  const [a, b, c] = await Promise.all([
    fetchValue("A", 100),
    fetchValue("B", 200),
    fetchValue("C", 150),
  ]);
  console.log("all values:", a, b, c);
}

loadAll();

src/04_parallel.js

javascript
/**
 * Compare timing of sequential await vs parallel await (Promise.all).
 */
function work(label, ms) {
  return new Promise((resolve) => setTimeout(() => resolve(label), ms));
}

async function sequential() {
  const start = Date.now();
  await work("A", 200);
  await work("B", 200);
  await work("C", 200);
  console.log("sequential:", Date.now() - start, "ms");
}

async function parallel() {
  const start = Date.now();
  await Promise.all([work("A", 200), work("B", 200), work("C", 200)]);
  console.log("parallel:", Date.now() - start, "ms");
}

(async () => {
  await sequential();
  await parallel();
})();

Common Mistakes

  1. Using `await` outside an `async` function β†’ SyntaxError.
  2. Writing independent tasks as sequential `await`s and wasting time.
  3. Skipping try/catch around an `await` and triggering an unhandled rejection.
  4. `forEach((x) => await ...)` doesn't actually wait β€” the callback isn't async.
  5. Forgetting that an `async` function returns a Promise and using the result directly.

FAQ

Q1. Can I use `await` at the module top level?

Yes β€” top-level await in ES modules (ES2022).

Q2. What happens if an async function throws?

Its returned Promise becomes rejected.

Q3. Should I prefer await or .then?

`await` usually reads better. `.then` can still be cleaner for simple branches and compositions.

Practice

  1. Use an async function to fetch a user and then their posts sequentially.
  2. Simulate parallel calls to multiple URLs with Promise.all.

homework/README.md

## 1. User + posts β€” Write fake `fetchUser(id)` and `fetchPosts(userId)`, then chain them in an async function and print the result.

## 2. Parallel requests β€” Start three fake URL requests with Promise.all and measure the total time.

See the `answer/` directory for solutions.

homework/answer/homework_01.js

javascript
/**
 * Fetch a user, then fetch their posts.
 */
function fetchUser(id) {
  return new Promise((resolve) => {
    setTimeout(() => resolve({ id, name: "Jimin" }), 100);
  });
}

function fetchPosts(userId) {
  return new Promise((resolve) => {
    setTimeout(() => resolve([{ id: 1, userId, title: "First post" }]), 100);
  });
}

async function main() {
  try {
    const user = await fetchUser(1);
    const posts = await fetchPosts(user.id);
    console.log(user.name, "'s posts:", posts);
  } catch (err) {
    console.error(err);
  }
}

main();

homework/answer/homework_02.js

javascript
/**
 * Send three fake URL requests in parallel and measure total time.
 */
function fakeFetch(url, ms) {
  return new Promise((resolve) => setTimeout(() => resolve(`${url} OK`), ms));
}

async function main() {
  const start = Date.now();
  const results = await Promise.all([
    fakeFetch("/a", 200),
    fakeFetch("/b", 250),
    fakeFetch("/c", 150),
  ]);
  console.log("results:", results);
  console.log("total time:", Date.now() - start, "ms");
}

main();

Next Lecture

[17_DOM_Selection_and_Inspection](../../05_DOM/17_DOM_선택과_쑰회/) β€” Working with HTML elements in the browser.

Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub β†—