Javascript 执行和延迟串联的承诺数组

Javascript 执行和延迟串联的承诺数组,javascript,node.js,promise,Javascript,Node.js,Promise,我正在尝试同步执行一系列函数。在调用下一个函数之前,每个函数都应该延迟3秒。 我一定是做错了什么,因为它们都是在3秒钟后同时调用的,而不是按顺序调用的 我做错了什么? var tasks = [] allGroups.forEach(function(group){ tasks.push(deleteFromGroup(group)) }) tasks.reduce(function(cur, next) { return cur.then(ne

我正在尝试同步执行一系列函数。在调用下一个函数之前,每个函数都应该延迟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);
  })
}

创建
任务
数组的方式不可避免地会导致超时同时发生,因为您在第一个
.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();
        }
    })();
});

p、 实际上,您可能希望将3s超时直接合并到循环中,而不是合并到
deleteFromGroup
-如上所述,上述代码(以及您的原始代码)在最后一次删除调用后3s才会显示“已完成”,但是我希望它真的应该在最后立即发生。

创建
任务的方式不可避免地会导致超时同时发生,因为您在第一个
.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();
        }
    })();
});

p、 实际上,您可能希望将3s超时直接合并到循环中,而不是合并到
deleteFromGroup
-如上所述,上述代码(以及您的原始代码)在最后一次删除调用后3s才会显示“已完成”,但是我希望它真的应该在最后立即发生。

您不需要在这里求助于回调和显式构造。实际上,您可以使用for循环,但不能在操作上使用,因为承诺是一个已经启动的操作

您只需合并两个循环:

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

在这里,您不需要求助于回调和显式构造。实际上,您可以使用for循环,但不能在操作上使用,因为承诺是一个已经启动的操作

您只需合并两个循环:

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

哇,这个效果非常好。非常感谢。哇,这个效果非常好。非常感谢。你为什么把答案代码粘贴到你的问题里?你不应该这样做,因为它会破坏上下文。你的代码最初工作得不好,我想问你为什么。我发现这是我自己的错误。我把问题倒回去了。谢谢。请-永远不要破坏已经有答案的部分问题。我不会。可悲的是,万能的mods来了,并将一个非常好的问题标记为重复…@Bergi这在功能上是相同的问题,但API是不同的。你为什么要将答案代码粘贴到你的问题中?你不应该这样做,因为它会破坏上下文。你的代码最初工作得不好,我想问你为什么。我发现这是我自己的错误。我把问题倒回去了。谢谢。请-永远不要破坏已经有答案的部分问题。我不会。可悲的是,万能的mods出现了,并将一个非常好的问题标记为重复…@Bergi这在功能上是相同的问题,但API是不同的。我(可能)已经修复了我答案中的
.catch
案例。这有点怪,我个人以前没有见过,我确实很喜欢,但我可以想象一些人在使用
.reduce
@Alnitak时会遇到麻烦。这可能是真的,但OP在他自己的代码中使用了reduce,所以我想这不是问题。我(可能)已经(可能)修复了我回答中的
.catch
案例。这有点怪,我以前没有亲眼见过,我确实很喜欢,但我可以想象一些人在使用
.reduce
@Alnitak时会遇到麻烦。这可能是真的,但OP在他自己的代码中使用了reduce,所以我认为这不是问题。