последовательно вызывать несколько setTimeouts с возвращением обещаний - PullRequest
0 голосов
/ 31 мая 2018

Я пытаюсь синхронно запустить массив асинхронных функций, используя eachSeries из async библиотеки.

Согласно этой SO Post , они говорят

Разница с async.eachSeries заключается в том, что каждая итерация будет ожидать завершения асинхронной операции перед началом следующей.

Это то, что я хочу.

Вопрос: Я не совсем понимаю, как использовать eachSeries для вызова следующего async setTimeout только после возвращения внутреннего обещания next() разрешается.

Я помещаю две асинхронные setTimeout функции в свою очередь:

this.dialogTimerQueue.push(this.getNextDialogTimer(data, 1000));
this.dialogTimerQueue.push(this.getNextDialogTimer(data2, 1000));
console.log(this.dialogTimerQueue); //  [101, 102]

Затем пытаюсь выполнить итерацию:

// https://caolan.github.io/async/docs.html#eachSeries
async.eachSeries(this.dialogTimerQueue, (result) => {

});

Проблема в , оба setTimeout работают параллельно.Они должны запускаться один за другим.

getNextDialogTimer возвращает новое setTimeout, которое само возвращает обещание next()

getNextDialogTimer: function(dialog, ms) {
    let foo = setTimeout(() => {
        // only when next() completes, call next in async series
        return this.next(dialog);
    }, this.npcDialogDelay * ms);

    console.log('Timeout: ', foo); // 101 or 102
    return foo;
},

next() обещание:

// Return promise
next: function(dialog) {
    var promiseTest = this.screenObj.conversation().addDialogToCenterScreen('npc', dialog, '');
    console.log('Next: ', promiseTest);
    return promiseTest;
},

Console.log отображается как:

enter image description here


    async.eachSeries(this.dialogTimerQueue, ({dialog, ms}, cb) => {
        setTimeout(() => {
            console.log('RESOLVING ' + dialog);
            this.next(dialog).then(() => {
                cb();
            });
        }, this.npcDialogDelay * ms);
    });

1 Ответ

0 голосов
/ 31 мая 2018

Проблема в том, что когда вы вызываете getNextDialogTimer, вы сразу же запускаете / устанавливаете timeout - это первая строка функции.Они запускаются, как только они добавляются в очередь, а это не то, что вам нужно.

Вместо этого вы можете поставить в очередь функцию вызываемый , которая при вызове запускает тайм-аут.Или вы можете просто поставить в очередь элементы dialog, ms, что, вероятно, будет легче понять, например:

const dialogTimerQueue = [];
const data = 'foo';
const data2 = 'bar';
const npcDialogDelay = 1;
const next = () => new Promise(resolve =>
  setTimeout(() => {
    console.log('next resolved');
    resolve();
  }, 500)
);

dialogTimerQueue.push({ dialog: data, ms: 1000 });
dialogTimerQueue.push({ dialog: data2, ms: 1000 });
async.eachSeries(dialogTimerQueue, ({ dialog, ms }, cb) => {
  setTimeout(() => {
    console.log('resolving ' + dialog);
    next().then(cb);
  }, npcDialogDelay * ms);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/async/2.6.1/async.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...