【问题标题】:Script stopping without errors after await Promise.all(...)在 await Promise.all(...) 之后脚本停止且没有错误
【发布时间】:2021-03-17 01:24:24
【问题描述】:

所以我遇到了一些非常奇怪的事情,我在一个循环中创建了 10 个 Promise 并将它们添加到一个数组中,但是在 await Promise.all() 之后,应用程序在某些情况下退出而没有错误。

我无法分享原始代码,但下面的代码在使用 nodejs 在 CentoOS 8 中运行时存在同样的问题:nodejs.x86_64 1:10.21.0-3.module_el8.2.0+391+8da3adc6

const shell = require("shelljs");
require('events').defaultMaxListeners = 15;

const run = async () => {
    await foo(DATA);
    console.log("Logging1"); // Get's printed
    await foo(OTHER_DATA_1);
    console.log("Logging2"); // Get's printed
    await foo(OTHER_DATA_2); // Usually at this level is where I no longer see the last log line
    // Here is also where the script exists without error (I've attached process.onExit and beforeExit but both print code 0
    console.log("More logging"); // Never get's printed
}

const foo = async (allData) => {
    let promises = [];
    for (const data of allData) {
        const command = "ecs-cli ....."; // An AWS ECS command (takes around ~1 minute)
        const myPromise = new Promise((resolve, reject) => {
            const cmdChildProcess = shell.exec(command, { silent: false, async: true });
            cmdChildProcess.on("close", (code) => {
                if (code === 0) {
                    const someData = doSomething(data);
                    console.log("Success!"); // Get's called
                    resolve(someData);
                } else {
                    console.error(`Process forcibly exited with code ${code}`); // Haven't seen this log line
                    reject(code);
                }
            });
        }).catch(error => {
            console.log(error); // Haven't seen this get called either
        });
        promises.push(myPromise);
    }
    await Promise.all(promises);
    console.log("I'm done with all the promises"); // Get's processed first couple of times
}

run();

我不确定我做错了什么,或者是因为我增加了 listenerMaxCount。 在增加它之前,我正在做类似的事情:

let promises = [];

...
//loop
promises.push(myPromise);
if(promises.length >= 6) {
    await Promise.all(promises);
    promises = [];
}
...

但这并没有改变同样的问题。

提前感谢所有帮助!

【问题讨论】:

  • 也许你可以添加一个setTimeout(()=>reject("timeout"), 50000) 在一段时间后强制拒绝
  • 哦 ...试试run().then(() => console.log('fini')); - 我似乎记得node.js在退出之前不会对待处理的承诺表示废话
  • @Sarabadu - 阅读代码 .... 命令 大约需要 1 分钟 - 为什么要在 50 秒后强制拒绝:p
  • @Bravo 你是对的setTimeout(()=>reject("timeout"), 120000) 它更好,但也不是一个很好的解决方案,我只会用它来测试。如果ecs-cli 命令可以提示等待用户交互或确认某些操作,那就太好了。
  • @Sarabadu - 我怀疑这与 Promises 没有最终确定有关 - 这是 node.js 的行为 - 它根本没有在退出之前等待承诺 - 我遇到过这种情况

标签: javascript node.js promise centos8


【解决方案1】:

虽然我仍然不能 100% 确定为什么会出现问题,但我可能已经发现了问题。

但基本上,如果我执行以下操作,它会起作用:

 for (const data of allData) {
        const command = "ecs-cli ....."; // An AWS ECS command (takes around ~1 minute)
        const myPromise = new Promise((resolve, reject) => {
            const cmdChildProcess = shell.exec(command, { silent: false, async: true });
            cmdChildProcess.on("close", (code) => {
                if (code === 0) {
                    resolve({});
                } else {
                    console.error(`Process forcibly exited with code ${code}`); // Haven't seen this log line
                    reject(code);
                }
            });
        }).then((data) => {
              doSomething(data); // Noy async
          })
          .catch(error => {
            console.log(error); // Haven't seen this get called either
        });
        promises.push(myPromise);
    }
    await Promise.all(promises);

如上所示,基本上我所做的只是从onClose 事件中删除了doSomething(data),并将其作为对then() 的承诺的解决方案,这似乎现在有效。

【讨论】:

  • doSomething的返回值是多少?它可能引发异常吗?
  • 我从未见过异常,它是成功或失败消息,但没有异常(它通过他们的 SDK 调用 AWS)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-19
  • 1970-01-01
  • 2015-07-15
  • 2019-11-28
相关资源
最近更新 更多