系列

时间:2015-11-13 13:06:39

标签: javascript node.js promise

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

2 个答案:

答案 0 :(得分:3)

您创建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();
        }
    })();
});

P.S。在实践中,您可能实际上想要将3s超时直接合并到循环中,而不是合并到deleteFromGroup中 - 因为上面的代码(以及您的原始代码)在3之后之后才会显示“已完成” / em>最后的删除调用,但我希望它真的应该在结束时立即发生。

答案 1 :(得分:2)

您无需在此处求助于回调和显式构造。事实上,您可以使用for循环 - 但不能执行操作,因为promise是已经开始的操作。

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

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