Остановить все вложенные обещания на пользовательском событии - PullRequest
0 голосов
/ 30 апреля 2019

У меня есть функция, которая запускает многие функции, основанные на обещаниях, в цикле, например:

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"?

Ответы [ 3 ]

1 голос
/ 30 апреля 2019

Это нормально, что ошибка, генерируемая внутри слушателя, не влияет на асинхронную функцию, потому что они не находятся в одном стеке вызовов.

Если вы хотите, чтобы все прекращалось при получении вашего сигнала, вам лучше использовать что-то вроде функции генератора, чтобы получить более точный контроль зерна.

1 голос
/ 01 мая 2019

Исключение не генерируется «родителем», оно генерируется в обработчике события.Это не имеет ничего общего с выполнением асинхронной функции.Вам понадобится что-то вроде

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(…) между каждыми двумя асинхронными действиями.

0 голосов
/ 30 апреля 2019

что-то в этом роде может быть, когда действие установлено в false, остановить то, что вы делаете в асинхронной функции

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