停止对自定义事件的所有嵌套承诺

Stop all nested promises on custom event

我有一个函数可以在循环中启动许多基于承诺的函数,例如:

let doSomething = (page, a, b) => {
    return new Promise(async(resolve, reject) => {

        eventBus.on('game::lag', () => {
            throw new Error('Game lag');
        });

        while(a.length > 0) {
            await doSomethingAsync();
            await doSomething2Async();

            while(b.length > 0) {
                await doSomething3();
                b = await getAsyncB();  
            }    
            a = await getAsyncA();  
        }
        resolve();
    });
};

现在关于来自程序其他部分的自定义事件,我希望此脚本终止并停止每个嵌套函数(doSomething* 函数)。此外,我在 doSomething* 函数中有一些间隔,但我希望一切都停止间隔。

我在示例代码中尝试过,成功抛出错误并在外部文件中捕获错误。但是我可以看到 doSomething* 个脚本仍在运行。

尽管我从 "parent" 抛出错误,但嵌套函数仍在运行是否正常?

可能会发生类似的情况,当 action 设置为 false 时,停止您在异步函数中所做的事情

let action = true
await doSomethingAsync(action)
async doSomethingAsync(action) { if(!action) stopWhatYouDo }

很正常,监听器内部抛出的错误不会影响异步函数,因为它们不在同一个调用堆栈中。

如果你想让一切都在收到你的信号时停止,你最好使用生成器函数之类的东西来获得更精细的粒度控制。

异常不是从 "parent" 中抛出的,而是在事件处理程序中抛出的。这与异步函数的执行无关。你需要像

这样的东西
async function doSomething(page, a, b) {
    const lagError = new Promise((resolve, reject) => {
        eventBus.on('game::lag', () => {
            reject(new Error('Game lag'));
        });
    });

    while(a.length > 0) {
        await Promise.race([lagError, doSomethingAsync()]);
        await Promise.race([lagError, doSomething2Async()]);

        while(b.length > 0) {
            await Promise.race([lagError, doSomething3()]);
            b = await Promise.race([lagError, getAsyncB()]);
        }    
        a = await Promise.race([lagError, getAsyncA()]);
    }
}

或者,您可以在处理程序中设置一个 error 标志,并在每两个异步操作之间进行 if (error) throw new Error(…) 检查。