在自定义事件上停止所有嵌套的Promise

时间:2019-04-30 19:16:01

标签: javascript events promise break cancellation

我有一个函数,它可以循环启动许多基于promise的函数,例如:

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*脚本仍在运行。

虽然我从“父母”那里抛出了错误,但嵌套函数仍在运行还是正常吗?

3 个答案:

答案 0 :(得分:1)

正常情况是,在侦听器中引发的错误不会影响异步功能,因为它们不在同一调用堆栈中。

如果您希望停止接收信号,最好使用类似生成器的功能来获得更精细的控制。

答案 1 :(得分:1)

不是从“父”对象引发异常,而是在事件处理程序中引发异常。这与异步功能的执行无关。您将需要

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(…)检查。

答案 2 :(得分:0)

类似的事情可能是,当操作设置为false时,停止您在异步功能中执行的操作

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