Common Asynchronous Mistakes
Asynchronous programming introduces new concepts:
Asynchronous programming introduces new concepts:
- Callbacks
- Promises
- async/await
Many beginner mistakes happen because asynchronous code does not always execute in the order you expect.
This chapter describes some of the most common mistakes and how to avoid them.
Share
Mistake 1: Forgetting await
The fetch() method returns a Promise.
If you forget await, you get the Promise instead of the downloaded data.
Wrong
Example Code
javascriptconst response = fetch("demo.txt");Correct
Example Code
javascriptconst response = await fetch("demo.txt");2: Using await Outside an Async Function
The await keyword can only be used inside an async function or at the top level of a JavaScript module.
Wrong
Example Code
javascriptfunction load() {
let response = await fetch("demo.txt");
}Correct
Example Code
javascriptasync function load() {
let response = await fetch("demo.txt");
}3: Assuming fetch() Fails on HTTP Errors
The Promise returned by fetch() is fulfilled when the server responds.
An HTTP error such as 404 Not Found does not reject the Promise.
Always check response.ok.
Correct
Example Code
javascriptconst response = await fetch("demo.txt");
if (!response.ok) {
throw new Error(response.status);
}4: Thinking Callbacks Are Asynchronous
A callback is simply a function passed to another function.
A callback may be called immediately or later.
The callback itself does not make code asynchronous.
Synchronous
Example Code
javascriptnumbers.forEach(show);Asynchronous
Example Code
javascriptsetTimeout(show,1000);5: Blocking the Event Loop
Long-running JavaScript blocks timers, user events, and screen updates.
Example
Example Code
javascriptfunction wait() {
let i = 4e9;
while(--i > 0);
}6: Expecting Screen Updates Immediately
Changing the DOM does not always update the screen immediately.
The browser usually waits until the current JavaScript task has finished before repainting the page.
Example
Example Code
javascriptmyDisplayer("Start");
wait();
myDisplayer("Done");7: Running Independent Tasks One After Another
If operations are independent, start them together.
Wrong
Example Code
javascriptawait fetch("a.json");
await fetch("b.json");
await fetch("c.json");Correct
Example Code
javascriptawait Promise.all([
fetch("a.json"),
fetch("b.json"),
fetch("c.json")
]);8: Using await Inside forEach()
The forEach() method does not wait for asynchronous callbacks.
Wrong
Example Code
javascriptfiles.forEach(async function(file){
await upload(file);
});Correct
Example Code
javascriptfor (const file of files) {
await upload(file);
}9: Forgetting Error Handling
Promises can be rejected.
Always handle possible errors.
Correct
Example Code
javascripttry {
const response = await fetch(url);
}
catch(err) {
console.log(err);
}10: Thinking setTimeout(..., 0) Runs Immediately
A zero-millisecond timeout means "run as soon as possible."
The callback still waits until the current JavaScript task has finished.
Example
Example Code
javascriptconsole.log("A");
setTimeout(() => console.log("B"),0);
console.log("C");Checklist
Before writing asynchronous code, ask yourself:
- Did I forget await?
- Did I check response.ok?
- Can these tasks run in parallel?
- Could this block the Event Loop?
- Am I handling rejected Promises?
- Do I really need a callback?
Summary
- Understand what your asynchronous API returns.
- Remember that fetch() returns a Promise.
- Use await correctly.
- Check for HTTP errors.
- Do not block the Event Loop.
- Run independent tasks in parallel.
- Always handle errors.
Interactive Code Examples
Wrong
javascriptconst response = fetch("demo.txt");Correct
javascriptconst response = await fetch("demo.txt");Wrong
javascriptfunction load() {
let response = await fetch("demo.txt");
}Correct
javascriptasync function load() {
let response = await fetch("demo.txt");
}Correct
javascriptconst response = await fetch("demo.txt");
if (!response.ok) {
throw new Error(response.status);
}Synchronous
javascriptnumbers.forEach(show);