Xav*_*_Ex 12 javascript multithreading synchronization callback
我在JavaScript开发了相当长的一段时间,但仍然净牛仔开发商,如的很多事情总是困扰着我的synching JavaScript的回调之一.
我将描述一个普通的场景时,这一问题将得到提升:我有一大堆的操作由一个for循环执行多次,并且每个操作都有一个回调.在for循环之后,我需要执行另一个操作,但是如果完成了for循环的所有回调,则此操作只能成功执行.
代码示例:
Run Code Online (Sandbox Code Playgroud)for ... in ... { myFunc1(callback); // callbacks are executed asynchly } myFunc2(); // can only execute properly if all the myFunc1 callbacks are done
建议的解决方案:
在循环开始时启动一个计数器,保持循环的长度,并且每个回调递减该计数器.当计数器达到0时,执行myFunc2.这实际上是让回调知道它是否是序列中的最后一个回调,如果是,则在完成时调用myFunc2.
问题:
终极问题:
有更好的解决方案吗?
Ja͢*_*͢ck 12
好消息是JavaScript是单线程的; 这意味着解决方案通常可以很好地与"共享"变量一起使用,即不需要互斥锁.
如果要序列化异步任务,然后执行完成回调,可以使用此辅助函数:
function serializeTasks(arr, fn, done)
{
var current = 0;
fn(function iterate() {
if (++current < arr.length) {
fn(iterate, arr[current]);
} else {
done();
}
}, arr[current]);
}
Run Code Online (Sandbox Code Playgroud)
第一个参数是需要在每次传递中传递的值数组,第二个参数是循环回调(如下所述),最后一个参数是完成回调函数.
这是循环回调函数:
function loopFn(nextTask, value) {
myFunc1(value, nextTask);
}
Run Code Online (Sandbox Code Playgroud)
传递的第一个参数是一个执行下一个任务的函数,它意味着传递给你的异步函数.第二个参数是值数组的当前条目.
我们假设asynch任务看起来像这样:
function myFunc1(value, callback)
{
console.log(value);
callback();
}
Run Code Online (Sandbox Code Playgroud)
它打印值,然后调用回调; 简单.
然后,设置整个运动:
serializeTasks([1,2, 3], loopFn, function() {
console.log('done');
});
Run Code Online (Sandbox Code Playgroud)
要并行化它们,您需要一个不同的功能:
function parallelizeTasks(arr, fn, done)
{
var total = arr.length,
doneTask = function() {
if (--total === 0) {
done();
}
};
arr.forEach(function(value) {
fn(doneTask, value);
});
}
Run Code Online (Sandbox Code Playgroud)
你的循环函数将是这个(只有参数名称更改):
function loopFn(doneTask, value) {
myFunc1(value, doneTask);
}
Run Code Online (Sandbox Code Playgroud)