[英]Spawning NodeJS worker thread inside of async function doesn't respect promise resolution
我有一個異步 function 啟動 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
function 工作正常,但console.log
語句在調用 encode() function 時立即執行 — encode_data
也是undefined
。 既然encode中的return
語句是在message
事件中,那async function的promise不應該在那個時候解決嗎?
因此, async
function 中的代碼不支持承諾。 您不能只是在async
function 中拋出隨機異步(但不是基於承諾的)代碼並期望任何事情都能正常工作。 async
function 可以與您await
的基於承諾的異步函數一起正常工作。 否則,它對那里的異步操作一無所知。 這就是為什么調用encode()
會立即返回而不等待任何事情完成。
此外, return transcode_data
在異步回調中。 在該回調中返回只是返回到調用回調的系統代碼並被盡職地忽略。 您不會從async
function 本身返回任何內容。 您正在返回該回調。
由於您的操作不是基於承諾的,要解決這個問題,您必須通過將其包裝在 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"));
}
},
僅供參考,此代碼假定您在 promise 中尋找的“結果”是您從該工作人員的第一條message
中獲得的transcode_data
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.