2013-07-19 8 views
12

के साथ async फ़ंक्शन लिखें, मैं नोड में नया हूं और नोड में एसिंक और ईवेंट व्यवहार फायदे का उपयोग करने का प्रयास करता हूं। मैं नोड से समझता था, इवेंट ऑब्जेक्ट के साथ जो कुछ भी संभालता है, वह एसिंक निष्पादन होगा।EventEmitter

var events = require("events"); 

var event = new events.EventEmitter(); 


event.on("work", function() { 

    for (var i = 0; i <= 10; i++) { 
     console.log("I do my work " + i); 
    } 

    event.emit("done"); 
}); 

var async = function (cb) { 

    event.on("done", cb); 
    event.emit("work"); 
    for (var i = 0; i <= 10; i++) { 
     console.log("Async " + i); 
    } 
} 


async(function() { 
    console.log("I am done callback!"); 
}); 

यह async निष्पादन है:
तो मैं इस, कोड को अपनाने पर विचार करने की कोशिश की थी? मेरी राय में नहीं! क्यों, क्योंकि मैं इस वाक्य कई पढ़ा था:

एक घटना निकाल दिया जाता है, तो जाने के लिए और कुछ करना है और फिर जब आप इसे समाप्त कर दिया है, वापस आना और मुझे बताओ, लेकिन तब तक मैं कुछ और करना होगा।

फास्ट फ़ूड रेस्तरां परिदृश्य की तरह। लेकिन इसके बाद के संस्करण कोड, जब घटना काम निकाल वाला, निम्न क्रम क्या होगा:

  1. कॉलबैक में जाने
  2. लूप के माध्यम से जाने
  3. उत्पादन मैं अपने काम n करना
  4. ईवेंट किया निकाल दिया
  5. आउटपुट मुझे कॉलबैक किया गया है!
  6. उत्पादन Async n

कारण है कि मैं कॉलबैक किया हूँ! Async एन से पहले उत्पादन करने वाला होगा? क्यों फास्ट फूड रेस्तरां परिदृश्य, जैसे

काम घटना निकाल दिया जाता है पसंद नहीं यहाँ है, जाने के लिए और आपको काम करना और वापस आने के लिए जब आप किया, इस बीच में मैं करूँगा उत्पादन Async n

यह क्या मैं घटना संचालित व्यवहार और नोड में async के बारे में समझने के लिए प्रयोग किया जाता है। लेकिन अब मैं बहुत उलझन में हूँ। मुझे पता है, जावास्क्रिप्ट एकल धागे पर काम करता है। मैं इवेंट एमिटर के साथ एसिंक फ़ंक्शन कैसे लिख सकता हूं? लेकिन मुझे लगता है कि यह संभव नहीं है, क्योंकि जब मैं एक घटना उत्सर्जित करता हूं, तो यह तुरंत हैंडलर निष्पादित करेगा।

उत्तर

18

मैं नोड से समझता था, जो घटना ऑब्जेक्ट के साथ संभालती है, यह एसिंक निष्पादन होगा।

यह गलत है। घटनाक्रम तुल्यकालिक हैं। आप एक श्रोता जोड़ते हैं, तो आप सिर्फ एक वस्तु में कॉलबैक बचत कर रहे हैं:

for (i = 0; i < len; i++) 
     listeners[i].apply(this, args); 

स्रोत:

this._events[type].push(listener); 

जब आप किसी ईवेंट फेंकना, तो आप सिर्फ एक सरणी प्रत्येक श्रोता पुनरावृत्ति कर रहे हैं और बुला कोड: https://github.com/joyent/node/blob/master/lib/events.js

यह एसिंक निष्पादन है? मेरी राय में नहीं!

आप सही हैं। अगर आप किसी भी I/O फ़ंक्शन को कॉल करते हैं या setImmediate, nextTick या टाइमर का उपयोग करते हैं तो यह एसिंक है, अन्यथा, यह तुल्यकालिक है।एक सिंक्रोनस कोड असीम रूप से लिखा जा रहा है इसे इसे एक असीमित कोड में परिवर्तित नहीं करता है।

मुझे कॉलबैक क्यों किया गया है! Async एन से पहले उत्पादन करने वाला होगा?

क्योंकि जब आप प्राप्त "किया" के लिए कॉलबैक आप "सीबी" कहते हैं:

event.on("done", cb); 

जब cb returns "Async n" पाश निष्पादित किया जाता है।

मैं ईवेंट एमिटर के साथ एसिंक फ़ंक्शन कैसे लिख सकता हूं?

setImmediate या process.nextTick का उपयोग करना।

यदि आप "मैं अपना काम करता हूं" लूप निष्पादन स्थगित करना चाहता हूं, तो आप nextTick के साथ लाइन को लपेट सकते हैं।

var events = require("events"); 

var event = new events.EventEmitter(); 


event.on("work", function() { 

    for (var i = 0; i <= 10; i++) { 
     console.log("I do my work " + i); 
    } 

    event.emit("done"); 
}); 

var async = function (cb) { 

    event.on("done", cb); 
    process.nextTick (function() {   //<----- 
     event.emit("work"); 
    });          //<----- 
    for (var i = 0; i <= 10; i++) { 
     console.log("Async " + i); 
    } 
} 


async(function() { 
    console.log("I am done callback!"); 
}); 

यह प्रिंट होगा: स्टैक में कोड पूरा हो चुका है के बाद

Async 0 
Async 1 
Async 2 
Async 3 
Async 4 
Async 5 
Async 6 
Async 7 
Async 8 
Async 9 
Async 10 
I do my work 0 
I do my work 1 
I do my work 2 
I do my work 3 
I do my work 4 
I do my work 5 
I do my work 6 
I do my work 7 
I do my work 8 
I do my work 9 
I do my work 10 
I am done callback! 
+0

घटना पाश फिर से अमल किया जाएगा। उदाहरण के लिए, मेरे पास कोड की 3 पंक्तियां हैं। पहला प्रक्रिया है .nextTick (dosomething) और अन्य बस console.log ("कुछ"); फिर ईवेंट लूप सही निष्पादित किया जाएगा? और इस लूप की शुरुआत में, process.nextTick() में पंजीकृत कॉलबैक निष्पादित होगा। सही? –

+0

निम्न कोड को देखें, जब मैं कॉल/test1 और अन्य ब्राउज़र/test2 में, मुझे/test2 पर प्रतिक्रिया प्राप्त करने के लिए काफी समय चाहिए, मेरे लिए यह/test1 ब्लॉक/test2 var express = आवश्यकता ('एक्सप्रेस'); var app = express(); app.get ('/', फ़ंक्शन (req, res) { res.send ('हैलो वर्ल्ड'); }); app.get ('/ test1', समारोह (अनुरोध, रेस) { \t (वर के लिए \t मैं = 0; i <= 100,000,000,000, i ++) { \t \t \t} res.send (' लूप समाप्त हो गया है '); }); app.get ('/ test2', फ़ंक्शन (req, res) { res.send ('No loop'); }); app.listen (3000); console.log ('पोर्ट 3000 पर शुरू हुआ एक्सप्रेस'); –

+2

/test1 इवेंट लूप को "अवरुद्ध" कर रहा है। यही कारण है कि नोड सीपीयू गहन कार्यों के लिए नहीं है। आप एक नई प्रक्रिया पैदा कर सकते हैं और इन कार्यों को कर सकते हैं। नोड में समरूपता को पूरी तरह से समझने के लिए इस आलेख को पढ़ें: http://neilk.net/blog/2013/04/30/why-you-should-use-nodejs-for-CPU-bound-tasks/ –

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