说我有两种方法:
function A(callback) { ... }
function B(callback) { ... }
我想执行:
功能C();
A和B完成后。
我们通常做的是将函数C放在回调中,如:
A(function() {
B(function() {
C();
});
});
现在如果A和B都需要很长时间,我不希望B在A完成后执行。相反,我想同时启动它们以提高性能 我在想的是实现类似信号量的东西(当然不是真正的信号量),它会在A和B都完成后触发事件。这样我就可以在活动中打电话给C.
我想知道的是,是否有任何库已实现上述功能?我相信我不是第一个想要这样做的人 任何帮助表示赞赏。
答案 0 :(得分:5)
扩展我的评论......
async
是Node.js的commonly used异步流控制库。
它的async.parallel()
可能会做得很好:
async.parallel([
function(done) {
A(function () {
done(null);
});
},
function(done) {
B(function () {
done(null);
});
}
], function (err) {
C();
});
这可能会缩短,但这取决于每个函数如何与回调交互,以及它们是否遵循error
的常见Node.js模式 - 第一次回调:
async.parallel([A, B], C);
答案 1 :(得分:2)
为了完整性并且如上所述,使用外部对象保持完成状态可以实现相同的结果,其中A()和B()检查另一个是否已完成,如果是,则调用C ()。如:
var results={};
function onComplete(){
if(results['A'] && results['B'] && !results['C']) {
C();
}
}
function A(){
// ...
results['A']=true;
onComplete();
}
function B(){
// ...
results['B']=true;
onComplete();
}
可以通过向A()和B()添加'isComplete'标志来替换结果对象,如:
function A(){
// ...
A.isComplete=true;
onComplete();
}
修改onComplete以检查这个新标志:
function onComplete(){
if(A.isComplete && ...
}
或者,使用相同的事件:
var util=require('util'),
events=require('events'),
EventEmitter=events.EventEmitter;
function F(){
EventEmitter.call(this); // init ancestor
}
util.inherits(F,EventEmitter); // assign ancestor
F.prototype.A=function(){
var self=this;
console.log('running A()');
setTimeout(function(){ // simulate long running code - 5 seconds
F.prototype.A.isComplete=true;
self.emit('complete','A');
},5000);
};
F.prototype.B=function(){
var self=this;
console.log('running B()');
setTimeout(function(){ // simulate long running code - 3 seconds
F.prototype.B.isComplete=true;
self.emit('complete','B');
},3000);
};
F.prototype.C=function(){
console.log('running C()');
};
var f=new F;
f.on('complete',function(which){ // onComplete handler
console.log(which+'() is complete');
if(F.prototype.A.isComplete && F.prototype.B.isComplete){
f.C();
}
});
// start it up
f.A();
f.B();
,在运行时,将产生:
>node example.js
running A()
running B()
B() is complete
A() is complete
running C()
>
答案 2 :(得分:1)
async.parallel([
function(){ ... },
function(){ ... }
], callback);
来自:https://github.com/caolan/async
所以在你的情况下:
async.parallel([funcA,funcB],funcC);
//function definitions
function funcA() {...}
function funcB() {...}
function funcC() {...}
没有模块我想它看起来像这样:
var numFuncs = 2;
A(D);
B(D);
and then
function D() {
if(numFuncs==0){ C(); } else {
numFuncs--;
}}
或者像这样:
A(D(C));
B(D(C));
function D() {
var x = process.funcsToCall= process.funcsToCall || {};
var f=arguments[0];
(!x.hasOwnProperty(f.name))?x[f.name]=0:x[f.name]++;
return function(){
(x[f.name]==0)?f():x[f.name]--;
}
}
答案 3 :(得分:0)
如果您在ES6上运行,则可以使用Promise.all。以下是重写的示例代码:
Promise.all([
new Promise((resolve) => A(() => resolve())),
new Promise((resolve) => B(() => resolve())),
]).then(() => {
C()
}).catch(err => {
// handle errors from function A, B and C
})
答案 4 :(得分:0)
我们可以 aync 和等待用于此目的,例如:
async function Foo(){
// function logic
}
并且这个Foo函数为:
await Foo();