Javascript NodeJs异步编程-协调并行调用
我指的是关于协调NodeJs中的并行调用的nodetuts教程。 有些事情我需要你的帮助来理解 callback1、callback12、callback3是需要并行执行的函数。每个人都需要自己的时间来执行 但它们的结果将按各自的顺序存储在结果数组中Javascript NodeJs异步编程-协调并行调用,javascript,node.js,asynchronous,callback,Javascript,Node.js,Asynchronous,Callback,我指的是关于协调NodeJs中的并行调用的nodetuts教程。 有些事情我需要你的帮助来理解 callback1、callback12、callback3是需要并行执行的函数。每个人都需要自己的时间来执行 但它们的结果将按各自的顺序存储在结果数组中 [resultofcallback1, resultofcallback2, resultofcallback3] 如前所述,最终回调的唯一约定是只执行一次并按正确顺序显示结果。 为此,我们有一个名为back的布尔值,以确保它只执行一次 mod
[resultofcallback1, resultofcallback2, resultofcallback3]
如前所述,最终回调的唯一约定是只执行一次并按正确顺序显示结果。
为此,我们有一个名为back的布尔值,以确保它只执行一次
module.exports = function composedCall(args, cb){
var pending = 0;
var results = [];
var calledBack = false;
callback1(args,handleResult());
callback2(args,handleResult());
callback3(args,handleResult());
function handleResult(){
var order = pending;
pending ++;
return function(err, result){
pending --;
if(err){
callback(err);
}else{
results[order] = result;
if(!pending){
callback(null, results);
}
}
}
}
function callback(err, value){
if(! calledBack){
calledBack = true;
cb(err, value)
}
}
}
function callback1(args ,callback){
setTimeout(callback, randomTimeout(), null, 1);
}
function callback2(args ,callback){
setTimeout(callback, randomTimeout(), null, 2);
}
function callback3(args ,callback){
setTimeout(callback, randomTimeout(), null, 3);
}
//utils
function randomTimeout(){
return Math.floor(Math.random() * 1e3);
}
function randomValue(){
return Math.floor(Math.random() * 1e10);
}
请参阅下面的代码
我的论点是在执行回调1时。
在handleResult
内部:pending=0
,order=0,pending增加到1
假设此回调执行时间最短
在该handleResult的返回函数内部,挂起的值递减
这使得挂起0
。假设此时没有其他回调(callback1,callback2)
达到其handlResult函数,因此挂起仍然为0。因此,这个if(!pending)断言和最终回调被称为callBack(null,results)
只输出一个结果,如[resultToCallback1',,'']
,其余两个为空,因为最终回调只应调用一次
module.exports = function composedCall(args, cb){
var pending = 0;
var results = [];
var calledBack = false;
callback1(args,handleResult());
callback2(args,handleResult());
callback3(args,handleResult());
function handleResult(){
var order = pending;
pending ++;
return function(err, result){
pending --;
if(err){
callback(err);
}else{
results[order] = result;
if(!pending){
callback(null, results);
}
}
}
}
function callback(err, value){
if(! calledBack){
calledBack = true;
cb(err, value)
}
}
}
function callback1(args ,callback){
setTimeout(callback, randomTimeout(), null, 1);
}
function callback2(args ,callback){
setTimeout(callback, randomTimeout(), null, 2);
}
function callback3(args ,callback){
setTimeout(callback, randomTimeout(), null, 3);
}
//utils
function randomTimeout(){
return Math.floor(Math.random() * 1e3);
}
function randomValue(){
return Math.floor(Math.random() * 1e10);
}
这是进行并行调用的正确方法吗
我错过什么了吗?你可以随时使用异步并行或类似的东西
对于手动实现,您可以执行以下操作之一:
1-长轮询已完成任务的数量。如果#已完成任务数==总#任务数=>最终回调
2-在每次回调结束时,发送一个“我完成”信号,并检查“我完成”信号的数量。如果“我完成了”信号的数量等于任务总数=>最终回调
看起来你要用第二种方法。检查您的代码,我看您没有遗漏任何方面,但您有一个大问题:
如果第一个任务在注册第二个任务之前完成,则只能使用第一个任务的结果执行最终回调。
重申:你注册任务的方式带来了竞争条件,这在很大程度上取决于你从随机超时中滚到足够高的位置,这样你就可以在你注册的任务全部完成之前注册所有任务
建议修复:在成功注册所有任务之前,不要启动任何任务。
另外:如果您从0开始挂起并执行order=pending,那么当您注册了3个任务但没有一个任务完成时,您将得到一个pending=2,并且在第二个任务完成且第三个任务仍在进行时,您将执行最后的回调。您缺少的是调用的是handleResult()
同步,因此您描述的场景永远不会发生。在执行第一个异步函数之前,Pending将增加3倍。请记住,setTimeout
s不会调用handleResult()
。他们将调用函数handleResult()
return。这些函数将被异步执行,handleResult()
被同步执行以生成它们。好了,现在它有意义了。很抱歉,我严重错过了那一点。如果callback1的setTimwout设置为0会怎么样。那会有什么不同吗?我知道这是回电话,只是好奇而已!setTimeout始终调用其回调异步,即使它设置为0。它只会在下一个滴答声中调用它。setTimeout
和process.nextTick
之间的区别在于setTimeout
处理所有异步事件,包括网络和磁盘io进程process.nextTick
是在所有其他事件之前处理的,因此如果您在无限循环中调用process.nextTick
,您可能会阻止所有其他进程(我发现这很难理解为什么我的数据包从未发送出去),谢谢。这真的很有帮助。