I've got an async function that launches a NodeJS worker thread like so:
encode : async (config) => {
if (isMainThread) {
const encode_worker = new Worker(`./service-encode.js`, { workerData: config });
encode_worker.on('message', (transcode_data) => {
log.info("%o", transcode_data);
return transcode_data;
});
encode_worker.on('error', (err) => { log.error(err)});
encode_worker.on('exit', (code) => {
if (code !== 0)
throw new Error(`Encoding stopped with exit code [ ${code} ]`);
console.log("* * * EXITED ENCODER WORKER * * *")
});
}
},
In the serivce-encode.js
file I've got the following code which uses async functions. Note that I am using postMessage
to signal that it is done.
var transcoder = require('./transcoder');
const {Worker, isMainThread, parentPort, workerData} = require('worker_threads');
console.log("* * * STARTING ENCODE THREAD * * *\n");
console.log(workerData);
transcoder.run(workerData)
.then((results) => {
transcode_data = results;
parentPort.postMessage(transcode_data);
})
.catch(err => { throw err });
Then, I use the following example code but the code in the 'message'
event from above fires off immediately. That is, it doesn't seem to wait until it's done:
encode(conf).then((encode_data) => { console.log("Encode Data :", encode_data);
The encode
function works fine, but the console.log
statement executes immediately when calling encode() function — also the encode_data
var is undefined
. Since the return
statement in the encode is in the message
event, shouldn't the promise of the async function be resolved at that time?
So, NOTHING about the code inside your
async
function supports promises. You can't just throw random asynchronous (but not promise-based) code inside anasync
function and expect anything to work. Anasync
function will work just fine with promise-based asynchronous functions that youawait
. Otherwise, it knows nothing about your asynchronous operations in there. That's why callingencode()
returns immediately without waiting for anything to complete.In addition,
return transcode_data
is inside an asynchronous callback. Returning inside that callback just goes back into the system code that called the callback and is dutifully ignored. You're not returning anything there from theasync
function itself. You're returning to that callback.Since your operation is not promise-based, to solve this, you will have to make it promise-based by wrapping it in a promise and then manually resolved or rejecting that promise when needed with the proper values. You can do that like this:
FYI, this code assumes that the "result" you're looking for here from the promise is the
transcode_data
you get with the firstmessage
from this worker.