2013-08-08 16 views
5

を実行する前に終了するのを待って、私は2つの方法を持っていると言う
関数Cを();
AとBの両方が終了した後。 AとBの両方に時間がかかる場合は、今、私はAが終了した後にBを実行したくないnodejs:私は実行したい</p> <pre><code>function A(callback) { ... } function B(callback) { ... } </code></pre> <p>::他の方法は

A(function() { 
    B(function() { 
    C(); 
    }); 
}); 

:私たちは通常、何をすべきか
は次のようにコールバックで関数Cを置くことです。パフォーマンスを向上させるためにそれらを同時に開始したいと考えています。
私が考えているのは、セマフォー(もちろんセマフォーではありません)のようなものを実装することです.AとBの両方が終了した後にイベントが発生します。私はイベント内からCを呼び出すことができます。

私が知りたいことは、上記の機能をすでに実装しているライブラリはありますか?私はそれをやりたい最初の人ではないと信じています。
ご迷惑をおかけして申し訳ございません。私のコメントに拡大すること

+1

[ ' async.parallel() '](https://github.com/caolan/async#parallel) –

答えて

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パターンに従うかどうか-firstコールバック:

async.parallel([A, B], C); 
+1

私は別のライブラリhttps://github.com/creationix/stepを見つけました。アイは同じことをやっている。とにかく、これは私の質問を解決します。ありがとう。 – yaoxing

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]--; 
    } 
} 
+0

第1のマニュアルは、AがBのコールバックDを呼び出してからBが起動するまでに時間がかかるので、より信頼性があります。または私は確信していません。 –

2

をし、上述したように、A()とB()の両方が完了したかどうかを確認する完了状態を保持するために外部オブジェクトを使用して同じ結果を達成することができ、 C()を呼び出します。

function A(){ 
    // ... 
    A.isComplete=true; 
    onComplete(); 
} 

そしてonCompleteのこの新しいを確認する変更:

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 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() 
> 
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 
}) 
0

我々はとaync は、例えば、この目的のためにを待つことができます:

async function Foo(){ 
    // function logic 
} 

と、このFooの機能として:ここではサンプルコードの書き換えがある

await Foo(); 
関連する問題