我试图执行一系列函数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);
})
}
答案 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")
});