NodeJS 即使在错误处理之后,节点进程也会退出

q5iwbnjs  于 2022-12-12  发布在  Node.js
关注(0)|答案(1)|浏览(137)

我用nodejs写了类似这样的东西

const someOtherOperation = async (message) => {
    try {
        await doSomeIoOperation(message);
    } catch (err) {
        something
        throw Error("Error doing someOtherOperation");
    } finally {
        await someCleanup();
    }

}

const someOperation = async (message) => {
    // something else
    await someOtherOperation(message);
    // something else
}

const main = async () => {
    let messagePromises = []
    let messages = await getMessages(); // fetching message from a message broker

    for (let message of messages) {
        messagePromises.push({ id: message.id, promise: someOperation(message) });
    }

    for (let messagePromise of messagePromises) {
        try {
            await messagePromise.promise;
        } catch (err) {
            console.log(err);
        }
    }

}

预期的行为是,即使其中一个promise出现错误,带有try catch的for循环也不应该结束。实际情况是,当sometherOperation方法出现错误时,我的进程突然结束。我不明白我在主循环中有一个try catch,从最内层函数传播的任何错误都应该在主函数的for循环中捕获,但它不是'我不知道怎么被抓住了,函数突然结束了

8yoxcaq7

8yoxcaq71#

Node.js对未处理拒绝的检测是不正确的。在被拒绝承诺的生命周期中有一些特定的点,引擎会在这些点检查是否存在处理程序,但它并不总是等到最后一个可能的时刻,因此它可能会错过我们添加处理程序的位置。
在我的代码中,我创建了一堆没有任何错误/拒绝处理程序的承诺。

messagePromises.push({ id: message.id, promise: someOperation(message) });

当我对第一个承诺做第一次等待时,它返回被拒绝,但在此期间考虑其他承诺也被拒绝,Nodejs引擎检查是否存在用于这些被拒绝的承诺的处理程序,因此,即使我为这些承诺添加了一个try catch,希望处理拒绝,nodejs引擎已经运行了一个处理程序的检查,但没有得到一个决定抛出一个未经处理的promise拒绝。
为了避开我的代码风格,我所做的是

const main = async () => {
    let messagePromises = []
    let messages = await getMessages(); // fetching message from a message broker

    for (let message of messages) {
        messagePromises.push({ id: message.id, 
        promise: someOperation(message).then(data=>[data,null]).catch(err=>[null,err]);
    }

    for (let messagePromise of messagePromises) {
        const [data,err] = await messagePromise .promise;
        if(err) {
           //some error handling code here.
        }
    }

}

对于这样一个成熟的语言来说,这是一个相当奇怪的行为。

相关问题