Promises & Async/Await
JavaScript runs on a single-threaded event loop. Non-blocking asynchronous behaviors are handled using callbacks, Promises, and the modern async/await wrapper syntax.
1 The Event Loop, Promises, and Async/Await
JavaScript executes tasks sequentially. When an asynchronous task (like a database query or network request) starts, JS sends it to the browser/system APIs and continues running other code. When the task finishes, it triggers its callback.
- Promise: An object representing the eventual completion (or failure) of an asynchronous operation, using `resolve` and `reject` states.
- Async/Await: Syntactical sugar that allows you to write asynchronous code that reads like synchronous code, improving readability.
2 Async Code
Let's run a program creating a simulated database query using Promises and parsing results with async/await:
JavaScript — Asynchronous Flow
▶ Run Code
// Simulated async network request
const fetchUser = (id) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) {
resolve({ id: id, name: "Alice", role: "Dev" });
} else {
reject(new Error("Invalid User ID"));
}
}, 1000);
});
};
// Parse promise using async/await
async function runDemo() {
console.log("Fetching user profile...");
try {
const user = await fetchUser(1); // Suspends execution until promise resolves
console.log("User Loaded:", user);
} catch (e) {
console.log("Error loading user: " + e.message);
}
}
runDemo();
3 Code Challenge
Challenge: Write a simulated async function called `fetchData` that returns a Promise resolving to "Data Received!" after 1.5 seconds. Call this function inside an `async` wrapper function using the `await` keyword, and print the resolved message to the console.