2013-08-08 8 views
5

निष्पादित करने से पहले समाप्त होने की प्रतीक्षा मैं 2 तरीकों कहते हैं:NodeJS: अन्य तरीकों

function A(callback) { ... } 
function B(callback) { ... } 

मैं निष्पादित करने के लिए करना चाहते हैं:
समारोह सी(); ए और बी दोनों समाप्त होने के बाद

क्या हम आम तौर पर कर की तरह कॉलबैक में समारोह सी डाल करने के लिए है: अब

A(function() { 
    B(function() { 
    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

,210

तो आपके मामले में:

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

पहला मैनुअल अधिक विश्वसनीय है क्योंकि यदि बी 'बी' से पहले भी कॉलबैक डी कॉल करता है तो शुरू करने का समय भी होता है। या नहीं, मुझे यकीन नहीं है। –

2

पूर्णता के लिए के लिए और जैसा ऊपर बताया गया है, वही परिणाम बाहरी ऑब्जेक्ट का उपयोग करके पूरा करने के लिए प्राप्त किया जा सकता है, जहां ए() और बी() दोनों यह देखने के लिए जांचें कि क्या दूसरा पूरा हो गया है और यदि ऐसा है, सी() को आमंत्रित करता है।

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

परिणाम वस्तु के रूप में, दोनों एक() और बी() के लिए एक '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(); 
,210

, जो जब चलाने के लिए, होगा उत्पादन:

>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 
} 

और के रूप में इस फू समारोह: यहाँ उदाहरण कोड पुनः लिखा जाता है

await Foo();