Menu
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP W3.CSS C C++ C# HOW TO BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR ANGULARJS GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SWIFT SASS VUE GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING INTRO TO HTML & CSS BASH RUST TOOLS

JS Tutorial

JS Home JS Introduction JS Where To JS Output JS Syntax JS Operators JS If Conditions JS Loops JS Strings JS Numbers JS Functions JS Objects JS Scope JS Dates JS Temporal  New JS Arrays JS Sets JS Maps JS Iterations JS Math JS RegExp JS Data Types JS Errors JS Debugging JS Style Guide JS Reference JS Projects  New JS Versions JS HTML DOM JS HTML Events JS HTML First

JS Advanced

JS Functions JS Objects JS Classes JS Asynchronous JS Modules JS Meta & Proxy JS Typed Arrays JS DOM Navigation JS Windows JS Web API JS AJAX JS JSON JS jQuery JS Graphics JS Examples JS Reference


JS Common Async Mistakes

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.

Mistake 1: Forgetting await

The fetch() method returns a Promise.

If you forget await, you get the Promise instead of the downloaded data.

Wrong

const response = fetch("demo.txt");

Correct

const 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

function load() {
  let response = await fetch("demo.txt");
}

Correct

async 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

const 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

numbers.forEach(show);

Asynchronous

setTimeout(show,1000);

The asynchronous behavior comes from setTimeout(), not from the callback.


5: Blocking the Event Loop

Long-running JavaScript blocks timers, user events, and screen updates.

Example

function 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

myDisplayer("Start");
wait();
myDisplayer("Done");

Did you know?

Changing an element with innerHTML updates the DOM immediately, but the browser normally waits until the current JavaScript task has finished before repainting the screen.

This is why long-running JavaScript can make a page appear frozen even though the DOM has already changed.


7: Running Independent Tasks One After Another

If operations are independent, start them together.

Wrong

await fetch("a.json");
await fetch("b.json");
await fetch("c.json");

Correct

await 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

files.forEach(async function(file){
  await upload(file);
});

Correct

for (const file of files) {
  await upload(file);
}

9: Forgetting Error Handling

Promises can be rejected.

Always handle possible errors.

Correct

try {
  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

console.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.

Next Chapter

The next page shows how to debug async code like a professional.

You will learn breakpoints, logging patterns, and why async errors feel invisible.

Debugging Asynchronous JavaScript


×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
sales@w3schools.com

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
help@w3schools.com

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookies and privacy policy.

Copyright 1999-2026 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.

-->