代码之家  ›  专栏  ›  技术社区  ›  user3871

顺序调用带有返回承诺的多个设置超时

  •  2
  • user3871  · 技术社区  · 7 年前

    我正在尝试使用 eachSeries async 图书馆。

    根据 this SO Post ,他们说

    与async.eachseries的区别在于,每次迭代都将等待异步操作完成,然后再开始下一次迭代。

    这就是我想要的。

    问题: 我不太懂怎么用 eachSeries 呼叫下一个 异步的 setTimeout 只有在归还内部承诺之后 next() 决定。

    我推两个异步 设置超时 我的队列中的函数:

    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) => {
    
    });
    

    问题是 ,两者 设置超时 并行运行。他们需要一个接一个地跑。

    getNextDialogTimer 返回新的 设置超时 这本身就是一个承诺 下()

    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;
    },
    

    下() 承诺:

    // 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 回复  |  直到 7 年前
        1
  •  1
  •   CertainPerformance    7 年前

    问题是当你打电话 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>