mr.Kame
mr.Kame

Reputation: 183

NodeJS await does not work within child process

I'm using Node v12.

I have a child process created with fork.

That child process executes an asynchronous task as follows:

// This is a child process
console.log('before async');
(async () => {
    try {
        console.log('before await')
        await asyncTask();
        console.log('after await')
    } catch (e) {
        console.log('ERROR!!')
    } finally {
        console.log('FINALLY!!')
    }
})();
console.log('after async');
return true;

The output I am getting is

before async
before await
after async

No error.

What am I doing wrong?

------------------------ (Edited)

To add mode details of what I need to do:

I'm currently using Parallel.js which uses fork.

I am open to use other libraries or tools.

Upvotes: 2

Views: 661

Answers (1)

jfriend00
jfriend00

Reputation: 707416

You aren't doing anything wrong. This is the expected ordering of events.

Using await in an async function only suspends execution of the specific function that the await is in and at that point the function then immediately returns a promise and execution continues on the next line of code after the function call. That is exactly what you are seeing here. That is the expected behavior.

Here's a step-by-step description of what's going on:

  1. console.log('before async'); executes.
  2. Your async IIFE starts and console.log('before await') executes.
  3. It executes await asyncTask(); and the current function execution is suspended and then that function immediately returns a promise.
  4. Since you do nothing with the function that the IIFE returns, the next line of code after that function call runs and this console.log('after async'); runs.
  5. Sometime later the promise that asyncTask() returned resolves and the await asyncTask() is done waiting and the execution of your function is resumed.

So, an async IIFE with an await in it (like you are using) does not pause the entire execution of the interpreter. It only pauses the internal execution of the IIFE. The lines of code right after it continue to execute as soon as the first await is encountered.


To advise on the proper way to write this code, we would need to see the larger context of how this code is being used and what is calling it and what that wants to wait for. There is no escaping an asynchronous operation. Using async/await does not make the overall operation suddenly become synchronous. It's still asynchronous and the caller still has to deal with using asynchronous programming techniques.

Probably, you should create a function that returns a promise when the forked process is complete. Then, the caller who wants to know when the forked process is complete must use that promise with either await or .then() to known when it's done. You can't hide that asynchronous coding inside a function and then treat the calling function as a normal synchronous function - Javascript does not work that way. Once anything in the calling chain is asynchronous, the whole calling chain is asynchronous and asynchronous coding techniques must be used to communicate back completion, errors and results.

Upvotes: 3

Related Questions