Quick Overview
`await` pauses the function, not the thread; everything outside it keeps running. Two sequential awaits cost the sum of both waits, where `Promise.all` costs only the longer of the two.
ES8 introduced async and await, syntactic sugar built directly on top of Promises.
It allows you to write asynchronous code that reads sequentially like synchronous code, avoiding long .then() chains.
Mark a function as async to allow pausing execution at any await expression until the Promise settles:
function fetchUser(id) {
return Promise.resolve({ id: id, name: "Alex" });
}
async function loadUserProfile() {
console.log("Fetching user...");
// Execution pauses here until Promise resolves
const user = await fetchUser(42);
console.log(`Loaded: ${user.name}`);
return user;
}
loadUserProfile();
Avoid sequential waterfalls when requests are independent:
// Slow Waterfall (Sequential)
// const user = await fetchUser();
// const posts = await fetchPosts();
// Fast Parallel Execution!
async function loadDashboard() {
const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
return { user, posts };
}
async Keyword: Using await outside an async function in older environments throws a syntax error.Promise.all()!Write it yourself. The tests below run against your code.
Use async/await for clean async logic. Next, let's catch runtime errors with try...catch!
Primitives copy by value and objects copy by reference, so `b = a` duplicates a number but shares an object. That single distinction explains most surprise mutations in a codebase.
`const` prevents reassignment, not mutation: a `const` object's properties can still be changed. `let` is scoped to its block, while `var` is function-scoped and leaks out of loops.
Only backticks interpolate: `${user}` reads the variable, while the identical text in quotes prints literally. Strings are immutable, so every method returns a new one rather than editing in place.