Skip to content
Lesson 5 of 15

Step 1 of 7 · Reading · ~4 min

Learn

Async JavaScript

async / await

async and await let you write promise code that reads top to bottom. They are not a new mechanism: every await is a promise step underneath. By the end of this lesson you can write async functions, handle their errors with try/catch, and avoid the two mistakes that make async code slow or silently wrong.

The two keywords

javascript
  • A function marked async always returns a promise. return x fulfils it with x, and a throw rejects it. async function f() { return 5; } behaves like function f() { return Promise.resolve(5); }.
  • await promise pauses this function only until the promise settles, then evaluates to its fulfilled value. If the promise rejects, await throws the reason at that line. await is only legal inside an async function.

While one function is paused, the rest of the program keeps running; nothing blocks.

What runs when

The body runs synchronously until the first await. Everything after it resumes later, as a microtask.

javascript

So code that depends on an async result must be after the await, or in a .then on the returned promise. Code placed after the call does not wait for it.

Errors: try / catch

throw raises an error and stops the function; a try block runs its code and, if something inside throws, jumps to the catch block instead of crashing. The try/catch/throw lesson later in this course covers both in full; this much is enough here. Because a rejected await throws, ordinary try/catch works, including around several awaits at once:

javascript

If you do not catch, the error rejects the promise the async function returned, and the caller must handle it. Inside a try, write return await promise rather than return promise, or the rejection escapes your catch.

Sequential or parallel

Awaiting one call after another makes them run one after another:

javascript

Rule: await when you need the result to continue. If two operations do not depend on each other, start them both first.

Loops

forEach ignores what its callback returns, so an async callback creates promises nobody waits for:

javascript

Use for (const x of list) { await ... } to go one at a time, in order, or await Promise.all(list.map(async x => ...)) to run them together.

No top-level await here

await outside an async function works only in ES modules. Your exercises run as plain scripts, so wrap the work in async function main() {...} and call main().

Common mistakes

  • Forgetting await: the variable holds a promise, and price * 2 becomes NaN.
  • Using async inside forEach and then reading the result immediately.
  • Awaiting independent operations one by one when they could overlap.
  • Wrapping the call in try but forgetting await, so the rejection happens later, outside the catch.
  • Putting code after the call and assuming the async function has finished.

Your exercise

Process a list in order with await, and keep going when one item fails. The starter provides the lookup and the driver that prints the total.

Up nextPromise PatternsAsync JavaScript

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…