簡體   English   中英

在異步 function 內部生成 NodeJS 工作線程不遵守 promise 分辨率

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM