JS enginesetTimeoutidlewait() promisegetUser() promise1const wait = (ms, v) =>2 new Promise((res) => setTimeout(res, ms, v));3async function getUser() {4 console.log("asking");5 const name = await wait(1000, "Ada");6 console.log("got " + name);7 return name.toUpperCase();8}9getUser().then((v) => console.log(v));10console.log("not blocked");Consoleasking:4not blocked:10got Ada:6ADA:9getUser()name = ?AdaADA
Back: the JavaScript engine (what runs now) and the timer, our stand-in serverMiddle: the microtask queue and two promises; front: user.js and the consoleWhite card: getUser's frame, which pauses at await and resumes laterAt the back, the JavaScript engine and a timer that stands in for a server. In the middle, the microtask queue and two promises. In front, the script and the console. getUser runs until await, then its frame (the white card) leaves the engine and waits on the pending promise, so line 10 can run. When the timer answers, the promise is fulfilled, a job to resume getUser goes into the microtask queue, and getUser carries on with the value. wait is a stand-in for a real request. fetch(url) works the same way: it returns a promise at once, and the network fulfils it later with a Response, so you write const res = await fetch(url).

The idea

  1. A server can take a second to answer. The JavaScript engine runs one thing at a time, so code must never sit and wait. async and await let one function pause while the rest of the program keeps running.

Running until await

Paused, not blocked

Resuming

What happens

// step 1/12 · idea
problem   asking a server takes time (often 100s of ms)
engine    runs one piece of code at a time
          a busy wait would freeze the whole page
promise   an object for a value that arrives later
await     pauses one async function until its promise settles
standard  ECMAScript (ECMA-262): async functions, await

wait is a stand-in for a real request. fetch(url) works the same way: it returns a promise at once, and the network fulfils it later with a Response, so you write const res = await fetch(url). Promise jobs are called microtasks. They run whenever the call stack empties, before the browser moves on to the next task such as a timer, a click or a redraw. The ECMAScript specification calls them jobs.