async/await
async functions always return a Promise. await pauses execution of the async function until the awaited Promise settles, then resumes with the resolved value or throws the rejection.
async/await is putting a bookmark in your novel. 'await' = put the book down, go do laundry, come back to the exact page when the dryer buzzes. The story reads top-to-bottom, but you are free between chapters.
await can only be used inside async functions (or top-level modules). Sequential await means each call waits for the previous — useful for ordering but inefficient when operations are independent. For parallel execution, use Promise.all([a(), b()]) with a single await. Errors thrown in async functions or from awaited rejections can be caught with try/catch. Forgetting await means you get a Promise object instead of the resolved value — one of the most common async bugs.
async/await desugars to generator functions and Promise machinery. An async function is essentially a state machine compiled by the transpiler or engine — each await point is a suspension/resumption boundary. V8 implements this with a native generator-like mechanism rather than actual generator objects, making it more efficient than babel-compiled async code. The spec requires that await always introduces at least two microtask hops (one to resolve, one to resume) — this was changed from three hops in V8 7.2 via an optimization (PromiseResolve inlining). Returning a native Promise from an async function also went from 3 hops to 2 in this optimization.
async/await is Promise syntax sugar that makes async code look synchronous. An async function always returns a Promise; await unwraps a Promise value inline. The key performance gotcha: sequential awaits run operations serially even when they could be parallel — always use Promise.all for independent concurrent operations. Error handling uses try/catch, which works identically to .catch() on a Promise chain.
await in a forEach callback does NOT pause the outer async function — Array.forEach is not async-aware. Each callback creates its own async context. Use for...of with await or Promise.all(array.map(async (item) => ...)) to correctly await iterations.