JavaScript handles slow operations (network requests, file reads) asynchronously. Instead of blocking the entire thread waiting for a response, it registers a callback and continues running. Async/await makes this look like synchronous code.
// Promises
function fetchUser(id) {
return new Promise((resolve, reject) => {
// Simulate an API call
setTimeout(() => {
if (id > 0) {
resolve({ id, name: "Alice" });
} else {
reject(new Error("Invalid user ID"));
}
}, 100);
});
}
// .then() chaining
fetchUser(1)
.then(user => {
console.log(user.name); // Alice
return fetchUser(2); // chain another promise
})
.then(user => console.log(user))
.catch(err => console.error(err.message));
// async/await — cleaner syntax for the same thing
async function getUser() {
try {
const user = await fetchUser(1);
console.log(user.name); // Alice
} catch (err) {
console.error(err.message);
}
}
getUser();
// fetch() — built-in for HTTP requests
async function getGitHubUser(username) {
const response = await fetch(`https://api.github.com/users/${username}`);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const data = await response.json();
return data;
}
async function main() {
try {
const user = await getGitHubUser("torvalds");
console.log(user.name); // Linus Torvalds
console.log(user.public_repos); // lots
} catch (err) {
console.error("Failed:", err.message);
}
}
main();
// Run multiple promises in parallel
async function fetchAll() {
const [user1, user2] = await Promise.all([
getGitHubUser("torvalds"),
getGitHubUser("gvanrossum"),
]);
console.log(user1.name, user2.name);
}
◆ Note
await can only be used inside async functions (or at the top level of ES modules). If you try to use it in regular code, you'll get a syntax error.