kus*_*nko 3 javascript asynchronous breeze q
我需要为数组的所有项动态执行函数,但是Array.forEach
按顺序执行,我需要在异步中执行.
items.forEach(function(item) {
doSomething(item);
});
Run Code Online (Sandbox Code Playgroud)
我试试这个:
var promises = [];
items.forEach(function(item) {
var promise = function() {
return Q.fcall(function() {
doSomething(item);
});
};
promises.push(promise());
});
Q.all(promises).then(function () {
otherFunction(datacontext.mainList); //use datacontext.mainList filled.
});
Run Code Online (Sandbox Code Playgroud)
但执行总是按顺序执行,我需要并行执行.
该doSomething(item)
方法:
function doSomething(item) {
var children = getChildren(item); //get data from local with manager.executeQueryLocally
var total = getTotal(children); //simple calculations
datacontext.mainList.push({
name: item.firstName() + ' ' + item.lastName(),
total: total
});
}
Run Code Online (Sandbox Code Playgroud)
请帮我.
Kri*_*wal 21
这个答案假设它doSomething
本身就是一个异步操作.这意味着它必须屈服于事件循环并且偶尔等待另一个事件至少一次.如果doSomething
是同步的,则异步编写它是没有好处的.
在复合异步作业的范围内,存在串行和并行变化.串行模型导致作业(n + 1)仅在作业(n)结束后开始.并行模型最初启动所有作业,并在所有作业完成后结束.在这两方面,我都可以给你提示.
同时,您可以使用Array map和Q.all,假设doSomething
接受一个值jobs
并返回一个promise:
return Q.all(jobs.map(doSomething))
Run Code Online (Sandbox Code Playgroud)
要按顺序执行作业,请使用Array reduce.
return jobs.reduce(function (previous, job) {
return previous.then(function () {
return doSomething(job);
});
}, Q());
Run Code Online (Sandbox Code Playgroud)
如果要以串行方式执行作业,但只根据第一个作业的结果继续执行下一个作业,则可以使用reduceRight
组合功能.
return jobs.reduceRight(function (next, job) {
return function (previous) {
return doSomething(job).then(function (result) {
if (result.isGood(previous)) return result;
return next(result);
});
});
}, function fallthrough(previous) {
throw new Error("No result was satisfactory");
})();
Run Code Online (Sandbox Code Playgroud)
如果你有一个包含需要按顺序执行的函数的数组,将前一个的输出提供给下一个的输入,你可以reduce
更简洁地使用.
return functions.reduce(Q.when, Q());
Run Code Online (Sandbox Code Playgroud)
Q自述文件中的教程涵盖了更多案例,我被告知有帮助https://github.com/kriskowal/q#tutorial