我想处理一系列的任务,并得到通知,只要这些任务块完成,一旦每项任务完成。我期望的输出应该是1,2,3 - 4,5,6 - 7 - 8
。使用我当前的实现,我得到了1,4,7,8 - 2,5 - 3,6
function handleTasks(tasks) {
var deferred = Q();
var promises = []
tasks.forEach(function (task) {
promises.push(function () {
return handle(task);
});
});
promises.reduce(Q.when, new Q()).then(function () {
// Finished inner hunk.
deferred.resolve();
});
return deferred.promise;
}
function handle(t) {
var deferred = Q.defer();
document.write("started " + t);
Q.delay(5000).then(function () {
document.write("finished " + t);
deferred.resolve();
});
return deferred.promise;
}
var deferred = Q();
var tasks = [[1, 2, 3], [4, 5, 6], [7], [8]];
var promises = []
tasks.forEach(function (task) {
promises.push(function () {
return handleTasks(task);
});
});
promises.reduce(Q.when, new Q()).then(function () {
// Finished all tasks
deferred.resolve();
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/q.js/0.9.6/q.js"></script>
发布于 2015-02-10 23:25:34
我真的不知道您的代码是如何产生任何输出的。您正在尝试使用一个承诺,就好像它们是延迟的,而您使用的是document.write()
,我可以想象它正在覆盖您的整个页面。
虽然不一定是一个bug,但您使用的是deferred antipattern。
因此,我不太清楚您为什么会得到这样的结果,但是这里有一种更干净的方法,可以产生所需的结果:
function handleTasks(tasks) {
var promiseFuncs = tasks.map(function (task) {
return function () {
return handle(task);
};
});
return promiseFuncs.reduce(Q.when, new Q()).then(function () {
console.log("finished " + JSON.stringify(tasks));
});
}
function handle(t) {
console.log("started " + t);
return Q.delay(5000).then(function () {
console.log("finished " + t);
return t;
});
}
var tasks = [[1, 2, 3], [4, 5, 6], [7], [8]];
var promiseFuncs = tasks.map(function (task) {
return function () {
return handleTasks(task);
};
});
promiseFuncs.reduce(Q.when, new Q());
<script src="http://cdnjs.cloudflare.com/ajax/libs/q.js/0.9.6/q.js"></script>
您还可以在这里使用帮助函数消除一些重复:
function runSequence(items, action) {
return items.map(function (item) {
return function () {
return action(item);
};
}).reduce(Q.when, new Q());
}
function handleTasks(tasks) {
return runSequence(tasks, handle).then(function () {
console.log("finished " + JSON.stringify(tasks));
});
}
function handle(t) {
console.log("started " + t);
return Q.delay(5000).then(function () {
console.log("finished " + t);
return t;
});
}
var tasks = [[1, 2, 3], [4, 5, 6], [7], [8]];
runSequence(tasks, handleTasks);
<script src="http://cdnjs.cloudflare.com/ajax/libs/q.js/0.9.6/q.js"></script>
https://stackoverflow.com/questions/28438261
复制相似问题