【问题标题】:NodeJS no code running after worker code finishes工作代码完成后NodeJS没有代码运行
【发布时间】:2021-08-06 09:09:07
【问题描述】:

我的工作代码有问题,目前我有一些代码可以扫描两个数据库表并找到一些匹配项,然后将一些数据从一个表添加到另一个创建一个新表。这是一大组数据,所以我正在使用工作线程来加快速度。

这一切都很好,但是一旦工作线程完成,就没有其他代码运行了也不跑。甚至parentResolve 也确实发生了,因为我没有看到console.log("parentResolve") 消息。

如果有人可以帮助我,我将不胜感激。

const calculateFactorialwithWorker = async () => {

    const SCCM = await ProgramDev.find({ "program name": { $not: { $regex: ".*[(]KB*[)]*" } } }).limit(8000)
    const sccmLength = SCCM.length

    mongoose.connection.close()

    return new Promise(async (parentResolve, parentReject) => {
        const numbers = [...new Array(sccmLength)].map((_, i) => i);

        const segmentSize = Math.ceil(sccmLength / userCPUCount);
        const segments = [];

        for (let segmentIndex = 0; segmentIndex < userCPUCount; segmentIndex++) {
            const start = segmentIndex * segmentSize;
            const end = start + segmentSize;
            const segment = numbers.slice(start, end)
            segments.push(segment);
        }
        try {
            const results = await Promise.all(
                segments.map(
                    segment =>
                        new Promise((resolve, reject) => {
                            const worker = new Worker(workerPath, {
                                workerData: segment,
                            });
                            worker.on('message', resolve);
                            worker.on('error', reject);
                            worker.on('exit', (code) => {
                                if (code !== 0)
                                    reject(new Error(`Worker stopped with exit code ${code}`));
                            });
                        })
                ));

            parentResolve(() => {

                console.log("parentResolve")

            })
        } catch (e) {
            parentReject(e)
        }
    });
};

calculateFactorialwithWorker().then(() => {

    console.log("Finished building merge table")
    LogData
})

【问题讨论】:

    标签: node.js multithreading promise node-worker-threads


    【解决方案1】:

    在 worker exit 事件中添加 if else 块。当 exitcode === 0 一起触发时,没有解决/拒绝来处理它。承诺不会被解决/拒绝。

    参考。 https://nodejs.org/api/worker_threads.html#worker_threads_event_exit

    另外,我稍微重写了你的代码,因为一些承诺包装是不必要的。

    const calculateFactorialwithWorker = async () => {
      try {
        const SCCM = await ProgramDev.find({
          "program name": { $not: { $regex: ".*[(]KB*[)]*" } },
        }).limit(8000);
    
        const sccmLength = SCCM.length;
    
        const numbers = [...new Array(sccmLength)].map((_, i) => i);
    
        const segmentSize = Math.ceil(sccmLength / userCPUCount);
        const segments = [];
    
        for (let segmentIndex = 0; segmentIndex < userCPUCount; segmentIndex++) {
          const start = segmentIndex * segmentSize;
          const end = start + segmentSize;
          const segment = numbers.slice(start, end);
          segments.push(segment);
        }
    
        const promises = segments.map(
          segment =>
            new Promise((resolve, reject) => {
              const worker = new Worker(workerPath, {
                workerData: segment,
              });
              worker.on("message", resolve);
              worker.on("error", reject);
              worker.on("exit", code => {
                if (code !== 0) {
                  reject(new Error(`Worker stopped with exit code ${code}`));
                } else {
                  resolve();
                }
              });
            })
        );
    
        await Promise.all(promises);
      } catch (err) {
        throw new Error(err);
      }
    };
    
    calculateFactorialwithWorker()
      .then(() => {
        console.log("Finished building merge table");
        LogData();
      })
      .catch(console.log)
      .finally(() => {
        mongoose.connection.close();
      });
    
    
    

    【讨论】:

    • 感谢您的帮助,我在上面的代码中仍然遇到同样的问题,现在我也收到错误:错误:工人停止并退出代码 0,但看起来代码仍在工作
    • @adamWadsworth,我想我知道为什么。 message 事件永远不会被工作人员触发,exit 事件实际上是被触发的。我添加了一个 if else 来处理 exit 事件。请检查我的更新
    • @ikhbjs console.log("Finished building merge table") 现在正在工作,但它仍然没有触发 Logdata 没有错误消息它刚刚结束并且该函数的第一行是 console.log("Starting logging data");
    • @adamWadsworth,也许应该改成LogData()?我只是用LogData 复制你的代码。无论如何,我在您的代码中看不到您的 LogData 函数。如果你能提供,可能会更清楚。
    • @ikhbjs 解决了问题,mongoose.connection.close(); 也存在问题,因为我需要在 logData 中再次调用数据库,所以移动了它,现在一切正常,谢谢你帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    相关资源
    最近更新 更多