在异步函数中生成 NodeJS 工作线程不遵守承诺解析



我有一个异步函数,可以启动NodeJS工作线程,如下所示:

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 * * *")
});
}
},

serivce-encode.js文件中,我得到了以下使用异步函数的代码。请注意,我使用postMessage来表示它已完成。

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 });

然后,我使用以下示例代码,但上面的'message'事件中的代码会立即熄灭。也就是说,它似乎不会等到它完成:

encode(conf).then((encode_data) => { console.log("Encode Data :", encode_data); 

encode函数运行良好,但console.log语句在调用encode((函数时会立即执行——encode_data变量也是undefined。既然encode中的return语句在message事件中,那么异步函数的promise当时不应该被解析吗?

因此,async函数中的任何代码都不支持promise。您不能只是在async函数中抛出随机异步(但不是基于promise的(代码,并期望任何东西都能工作。async函数与await中基于promise的异步函数配合使用会很好。否则,它对其中的异步操作一无所知。这就是为什么调用encode()会立即返回而不等待任何操作完成的原因。

此外,return transcode_data在一个异步回调中。在回调内部返回只会返回到调用回调的系统代码中,并被完全忽略。您不会从async函数本身返回任何内容。您正在返回回拨。

由于您的操作不是基于promise的,因此要解决此问题,您必须将其包装在promise中,然后在需要时使用适当的值手动解决或拒绝该promise,从而使其基于promise。你可以这样做:

encode: (config) => {
if (isMainThread) {
return new Promise((resolve, reject) => {
const encode_worker = new Worker(`./service-encode.js`, { workerData: config });
encode_worker.on('message', (transcode_data) => {
log.info("%o", transcode_data);
resolve(transcode_data);
});
encode_worker.on('error', (err) => {
log.error(err)
reject(err);
});
encode_worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Encoding stopped with exit code [ ${code} ]`));
}
console.log("* * * EXITED ENCODER WORKER * * *")
});
});

} else {
// should return a promise from all calling paths
return Promise.reject(new Error("Can only call encode() from main thread"));
}
},

仅供参考;结果";你在这里寻找的承诺是你从这个工人那里得到的第一个messagetranscode_data

最新更新