Sparround

Promises and async/await

JavaScript is single-threaded: long operations (network, files, browser commands) don't block execution — the result comes back "later" via a Promise.

A Promise has 3 states: pendingfulfilled (success) or rejected (error).

async/await is the modern, readable way to work with Promises:

  • an async function always returns a Promise
  • await waits for the Promise to settle and unwraps the value
  • in Playwright nearly every command returns a Promise: await page.click(...), await page.goto(...)

A forgotten `await` is automation's #1 bug. page.click('#save') (without await) sends the command but doesn't wait for it — the next line runs in parallel and the test goes flaky. Playwright's no-floating-promises lint rule catches this — add it to every project.

Parallel waiting: await independent Promises in parallel, not sequentially:

  • Promise.all([p1, p2]) — waits for all; if one rejects, the whole thing rejects
  • Promise.allSettled([...]) — returns every outcome (success/failure mixed)
  • Promise.race([...]) — returns the first to settle (useful for timeout patterns)

📚 Sources and documentation