顺序调用多个setTimeouts并返回promises

时间:2018-05-31 01:17:53

标签: javascript asynchronous

我正在尝试使用async库中的eachSeries同步运行一系列异步函数。

根据this SO Post,他们说

  

与async.eachSeries的区别在于每次迭代都会等待异步操作完成,然后才能启动下一个异步操作。

这就是我想要的。

问题:我不太了解如何在返回内部承诺{{之后} eachSeries之后调用下一个async setTimeout 1}}解决。

我将两个异步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()

Console.log显示为:

enter image description here

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

1 个答案:

答案 0 :(得分:1)

问题在于,当您致电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>
&#13;
&#13;
&#13;