【问题标题】:Executing and delaying array of promises in series [duplicate]连续执行和延迟一系列承诺[重复]
【发布时间】:2015-11-13 22:23:59
【问题描述】:

我正在尝试使用同步执行一系列功能。每个函数都应该在调用下一个函数之前延迟 3 秒。 我一定是做错了什么,因为它们都是在 3 秒后同时调用的,而不是按顺序调用的。

我做错了什么?

var tasks = []
    allGroups.forEach(function(group){
      tasks.push(deleteFromGroup(group))
    })

    tasks.reduce(function(cur, next) {
      return cur.then(next);
    }, Promise.resolve()).then(function() {
     console.log("all executed")
    });
  })
}

function deleteFromGroup(group){
  return new Promise(function(resolve, reject) {
    setTimeout(function(){
      console.log(group.id)
      resolve()
     }, 3000);
  })
}

【问题讨论】:

  • 为什么将答案代码粘贴到问题中?你不应该这样做,因为它会破坏上下文。
  • 您的代码最初不能正常工作,我想问您为什么。我发现这是由于我自己的错误。我回滚了这个问题。
  • 谢谢。请 - 切勿破坏已发布答案的部分问题。
  • 我不会。可悲的是,万能的模组来了,并将一个非常好的问题标记为重复......
  • @Bergi 它在功能上是同样的问题,但是 API不同的。

标签: javascript node.js promise


【解决方案1】:

您创建 tasks 数组的方式不可避免地会导致所有超时(大约)同时发生,因为您在第一个 .forEach 循环中同时创建任务。

要达到您需要的效果,您实际上需要在解决当前任务之前不要创建下一个任务。这是实现该目标的伪递归方式:

return new Promise(resolve, reject) {
    var groups = allGroups.slice(0);  // clone
    (function loop() {
        if (groups.length) {
            deleteFromGroup(groups.shift()).catch(reject).then(loop);
        } else {
            console.log("all executed")
            resolve();
        }
    })();
});

附言在实践中,您实际上可能希望将 3s 超时直接合并到循环中,而不是合并到 deleteFromGroup - 正如上面所写的代码(和您的原始代码)在 3s after之前不会显示“完成” > 最后的删除调用,但我希望它真的应该在最后立即发生。

【讨论】:

  • 哇,这个效果非常好。非常感谢。
【解决方案2】:

您无需在此处使用回调和显式构造。实际上,您可以使用 for 循环 - 但不能在操作上使用,因为 Promise 是一个已经开始的操作。

您需要做的就是合并两个循环:

allGroups.reduce(function(cur, next) {
  return cur.then(function(){ return deleteFromGroup(next) });
}, Promise.resolve()).then(function() {
 console.log("all executed")
});

【讨论】:

  • 我(可能)在我的回答中修复了 .catch 的情况。这有点古怪,我以前没有亲眼见过,我确实很了解,但我可以想象有些人在努力使用 .reduce
  • @Alnitak 可能是真的,但是 OP 在他自己的代码中使用了 reduce,所以我认为这不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-23
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
相关资源
最近更新 更多