Synchronous vs. Asynchronous

Most of the code you write is synchronous. This means it runs in strict sequence: each line of code executes one after the next, and the program will not move to line 2 until line 1 has completely finished executing.

// Synchronous Example
console.log("I print first");
console.log("I print second");
console.log("I print third");

Asynchronous Execution

Asynchronous (or async) code allows certain tasks to run concurrently. While the main thread continues running subsequent lines of code, async tasks are offloaded to run outside the main execution flow, typically waiting for some external event or timer to finish.

A common example of asynchronous behavior is the built-in setTimeout() function.

console.log("I print first");

// This is scheduled for the future, so the main thread moves on immediately
setTimeout(() => {
  console.log("I print third because I'm waiting 100 milliseconds");
}, 100);

console.log("I print second");

// Output:
// I print first
// I print second
// I print third because I'm waiting 100 milliseconds

In the example above, setTimeout accepts a callback function and a delay in milliseconds. It effectively “sets aside” the function, allowing the main thread to immediately execute console.log("I print second"). Once the 100 milliseconds have passed, the callback function is queued up and executed as soon as the main thread is available.