Gieted
Gieted

Reputation: 895

Why async funtions are not asynchronous in node.js?

This question might sound weird but to my understanding, the asynchronous code should execute independently from the main thread. Look at this code:

async function async() {
    while (true) {

    }
}

async()
console.log('test')

While loop wouldn't block this code if the whole function was asynchronous and "test" should be logged to the console, but it doesn't happen. Why it is this way?

Upvotes: 0

Views: 76

Answers (2)

Etheryte
Etheryte

Reputation: 25310

In Javascript, async functions are only asynchronous, all code still executes on a single thread. (The exceptions to this is when you use something like threads in Node or web workers in the browser, see the links for more info on that.)

To illustrate what this means, let's define two sample functions:

function halts() {
  const start = Date.now()
  while (Date.now() < start + 2000);
}

function resolves() {
  return new Promise((resolve) => setTimeout(resolve, 2000));
}

The first function will block the thread for roughly 2 seconds, returning nothing, the second function will return a promise that will resolve after a similar period of time.

When you're using these functions, the crucial difference is that when calling the first one, all execution blocks up until the function completes, since everything is running on a single thread:

function halts() {
  const start = Date.now()
  while (Date.now() < start + 2000);
}

const before = Date.now();
halts();
const after = Date.now();
console.log(`execution halted for ${after - before}ms`);

The difference when using asynchronous operations (regardless of whether you use promises or async-await for the implementation) is that you can allow the main thread to take on other work until you wait, for example, for a network request to complete.

function resolves() {
  return new Promise((resolve) => setTimeout(resolve, 2000));
}

const interval = setInterval(() => {
  console.log('ping');
}, 500);

const before = Date.now();

resolves().then(() => {
  clearInterval(interval);
  console.log('promise resolved');
});

const after = Date.now();
console.log(`execution halted for ${after - before}ms`);

Notice how the second example continues with the execution of the rest of the code immediately, instead of halting everything. The async operation isn't done on a separate thread, it's simply deferred for later on the same thread.

For a more technical explanation, Deceze's answer is a good short summary, this video by Jake Archibald is a good general overview as well.

Upvotes: 1

deceze
deceze

Reputation: 522015

Asynchronous does not mean that the code is running in a different thread. Asynchronous execution is cooperative multitasking within the same thread. Functions yield execution back to the event loop through await or by finishing their execution, and the event loop will continue their execution/execute callbacks upon certain events (e.g. network request having finished, or a setTimeout timer having completed). It's still entirely possible for one function to hog the thread using an infinite loop.

Upvotes: 1

Related Questions