2012-03-30 9 views
9

मेरे पास एक नोड एप्लिकेशन है जो एक वेब अनुप्रयोग नहीं है - यह लौटने से पहले एसिंक्रोनस कार्यों की एक श्रृंखला को पूरा करता है 1. लौटने से पहले, प्रोग्राम के परिणाम कंसोल पर मुद्रित होते हैं।एक node.js फ़ंक्शन कैसे लिखें जो 'वापसी' से पहले किसी ईवेंट को आग लगने की प्रतीक्षा करता है?

मैं कैसे सुनिश्चित कर सकता हूं कि लौटने से पहले सभी एसिंक्रोनस काम पूरा हो जाए? मैं res.end() को कॉल करने से पहले पूरा किए गए सभी कार्यों को सुनिश्चित करके वेब एप्लिकेशन में ऐसा कुछ हासिल करने में सक्षम था, लेकिन मेरे पास स्क्रिप्ट रिटर्न देने से पहले कॉल करने के लिए अंतिम 'ईवेंट' के बराबर नहीं है।

वर्तमान में मेरे (टूटा हुआ) फ़ंक्शन के लिए नीचे देखें, कॉलस्टैक खाली होने तक प्रतीक्षा करने का प्रयास करें। मैंने अभी पाया है कि यह एक तरह का बकवास दृष्टिकोण है क्योंकि नोड प्रक्रिया के लिए इंतजार कर रहा है हब प्रोसेसऑबजविथरफ में नामक एसिंक्रोनस कार्यों में से किसी एक को दर्ज करने से पहले पूरा करने के लिए।

function processHub(hubFileContents){ 
    var callStack = []; 
    var myNewObj = {}; 
    processObjWithRef(samplePayload, myNewObj, callStack); 
    while(callStack.length>0){ 
     //do nothing 
    } 
    return 1 
} 

नोट: मैं कई बार कोशिश की है कि पहले (How can I make this call to request in nodejs synchronous? पर अपने संबंधित सवाल देखें) तो कृपया जवाब और खाते में वहाँ टिप्पणियाँ 'के आधार पर कोई जवाब सुझाव से पहले ले async तरह पुस्तकालयों के साथ इस तरह का व्यवहार प्राप्त करने के लिए बस asynch का उपयोग करें।

+1

"मैं कैसे सुनिश्चित कर सकता हूँ सब अतुल्यकालिक काम पूरा हो गया है ? " एक गैरकानूनी सवाल है - जब तक सभी एसिंक्रोनस कार्यों को पूरा नहीं किया जाता है तब तक नियंत्रण को कभी भी खोल में वापस नहीं किया जाता है, इसलिए आखिरी एसिंक्रोनस फ़ंक्शन पूरा होने तक कंसोल आउटपुट को छोड़कर मेरी समस्या ठीक हो जाती है। उत्तर सबमिट करने के लिए सभी को धन्यवाद। – Trindaz

उत्तर

5

समस्या आपके फ़ंक्शन के डिज़ाइन के साथ है। आप सिंक्रोनस परिणाम को उन कार्यों की एक सूची को वापस करना चाहते हैं जो असीमित रूप से निष्पादित किए जाते हैं।

आपको अपने कार्य को एक अतिरिक्त पैरामीटर के साथ कार्यान्वित करना चाहिए जो कॉलबैक होगा जहां आप कुछ उपभोक्ता के लिए कुछ करने के लिए परिणाम (इस मामले में, 1) डाल देंगे।

इसके अलावा आपको अपने आंतरिक कार्य में कॉलबैक पैरामीटर होना चाहिए, अन्यथा आपको यह नहीं पता होगा कि यह कब समाप्त होता है। यदि यह आखिरी बात संभव नहीं है, तो कॉलस्टैक सरणी पॉप्युलेट होने पर परीक्षण करने के लिए आपको किसी प्रकार का मतदान करना चाहिए (शायद सेटइंटरवाल का उपयोग करना)।

याद रखें, जावास्क्रिप्ट में आपको कभी भी व्यस्त प्रतीक्षा नहीं करना चाहिए। यह आपके प्रोग्राम को पूरी तरह लॉक कर देगा क्योंकि यह एक ही प्रक्रिया पर चलता है।

1

समस्या यह है कि node.js एकल-थ्रेडेड है, जिसका अर्थ है कि यदि कोई फ़ंक्शन चलता है, तो कुछ भी नहीं चलता है (ईवेंट-लूप) जब तक कि फ़ंक्शन वापस नहीं आ जाता है। इसलिए आप एसिंक सामग्री के बाद इसे वापस करने के लिए फ़ंक्शन को अवरुद्ध नहीं कर सकते हैं।

उदाहरण के लिए, आप एक काउंटर वेरिएबल सेट कर सकते हैं, जो कि आपके एसिंक कोड से कॉलबैक फ़ंक्शन (जो कार्य समाप्त होने के बाद कहा जाता है) का उपयोग करके काउंटर को एसिंक कार्यों और कमी को शुरू करता है।

5

आप लौटने से पहले एक असीमित घटना की प्रतीक्षा नहीं कर सकते - यह असीमित की परिभाषा है! इस प्रोग्रामिंग शैली में नोड को मजबूर करने की कोशिश करने से आपको दर्द हो सकता है। callstack खाली है या नहीं, यह देखने के लिए समय-समय पर जांच करना एक बेवकूफ उदाहरण होगा।

var callstack = [...]; 

function processHub(contents) { 
    doSomethingAsync(..., callstack); 
} 

// check every second to see if callstack is empty 
var interval = setInterval(function() { 
    if (callstack.length == 0) { 
    clearInterval(interval); 
    doSomething() 
    } 
}, 1000); 

इसके बजाय, नोड में async सामान करने के लिए हमेशा की तरह अपने कार्य करने के लिए एक कॉलबैक लागू करने के लिए है।

function processHub(hubFileContents, callback){ 
    var callStack = []; 
    var myNewObj = {}; 
    processObjWithRef(samplePayload, myNewObj, callStack, function() { 
    if (callStack.length == 0) { 
     callback(some_results); 
    } 
    }); 
} 

तुम सच में कुछ वापस जाने के लिए, promises की जाँच चाहते हैं; वे किसी घटना को तत्काल या भविष्य में किसी बिंदु पर हल करने की गारंटी देते हैं जब उन्हें हल किया जाता है।

function processHub(hubFileContents){ 
    var callStack = []; 
    var myNewObj = {}; 
    var promise = new Promise(); 

    // assuming processObjWithRef takes a callback 
    processObjWithRef(samplePayload, myNewObj, callStack, function() { 
    if (callStack.length == 0) { 
     promise.resolve(some_results); 
    } 
    }); 

    return promise; 
} 

processHubPromise = processHub(...); 
processHubPromise.then(function(result) { 
    // do something with 'result' when complete 
}); 
0

आप डिजाइन और अतुल्यकालिक रूप से सोच है, जो पहली बार में करने के लिए इस्तेमाल करने के लिए थोड़ा समय लग सकता है शुरू करने के लिए की आवश्यकता होगी। फ़ंक्शन कॉल के बाद आप "वापसी" जैसी किसी चीज़ से कैसे निपटेंगे इसका एक सरल उदाहरण है।

function doStuff(param, cb) { 
    //do something 
    var newData = param; 
    //"return" 
    cb(newData); 
} 

doStuff({some:data}, function(myNewData) { 
    //you're done with doStuff in here 
}); 

वहाँ भी NPM पर उपलब्ध async पुस्तकालय में सहायक उपयोगिता कार्यों के एक बहुत कुछ है।

3

deasync आपकी समस्या का समाधान करने के लिए तैयार है। बस

require('deasync').loopWhile(function(){return callStack.length>0;}); 
1

Node.js एक एकल थ्रेड घटना पाश पर चलता है और मैं/हे संचालन जैसे विभिन्न बातें, करने के लिए अतुल्यकालिक कॉल का लाभ उठाता है साथ

while(callStack.length>0){ 
    //do nothing 
} 

बदलें।

आप अतुल्यकालिक संचालन अतिरिक्त कोड निष्पादित करने से पहले खत्म करने के लिए के एक नंबर के लिए प्रतीक्षा करने के लिए आप Async उपयोग करके देख सकते की जरूरत है - लौटने से पहले

Node.js Async Tutorial

संबंधित मुद्दे