2016-05-11 12 views
5

से इवेंट हैंडलर से अलग व्यवहार करता है मेरे पास EventEmitter तक फैले किसी ऑब्जेक्ट के दो उदाहरण हैं और finish नामक किसी ईवेंट को सुनते हैं। अगर मैं कन्स्ट्रक्टर के बाहर इवेंट हैंडलर सेट करता हूं तो सब कुछ अपेक्षित काम करता है। प्रत्येक उदाहरण finish के अवसर को सुनता है जो यह ट्रिगर करता है। लेकिन अगर मैं कन्स्ट्रक्टर के अंदर इवेंट हैंडलर सेट करता हूं, तो केवल इंस्टेंस ने दूसरे सुनवाई की और घटना पर प्रतिक्रिया व्यक्त की, या ऐसा लगता है।कन्स्ट्रक्टर में इवेंट हैंडलर कन्स्ट्रक्टर

var util = require('util'); 
var EventEmitter = require('events').EventEmitter; 
var fs = require('fs'); 

var NEXT_ID = 0; 
var MyEmitter = function() { 
    EventEmitter.call(this); 
    this.id = NEXT_ID; 
    NEXT_ID++; 
    console.log('CREATED EMITTER WITH ID:', this.id) 
    self = this; 
    this.on('finish', function() { 
    console.log('FINISH EVENT . CONSTRUCTOR LISTENER .', 
       'LISTENER ID:', self.id, 
       '. ORIGINATOR ID:', this.id); 
    }); 
}; 

util.inherits(MyEmitter, EventEmitter); 

var setFinishListener = function(emitter) { 
    emitter.on('finish', function() { 
    console.log('FINISH EVENT . NON-CONSTRUCTOR LISTENER .', 
       'LISTENER ID:', emitter.id, 
       '. ORIGINATOR ID:', this.id); 
    }); 
} 

var emitter0 = new MyEmitter(); 
var emitter1 = new MyEmitter(); 

setFinishListener(emitter0); 
setFinishListener(emitter1); 

emitter0.emit('finish'); 
emitter1.emit('finish'); 

// The following is logged to the console: 
// FINISH EVENT . CONSTRUCTOR LISTENER . LISTENER ID: 1 . ORIGINATOR ID: 0 
// FINISH EVENT . NON-CONSTRUCTOR LISTENER . LISTENER ID: 0 . ORIGINATOR ID: 0 
// FINISH EVENT . CONSTRUCTOR LISTENER . LISTENER ID: 1 . ORIGINATOR ID: 1 
// FINISH EVENT . NON-CONSTRUCTOR LISTENER . LISTENER ID: 1 . ORIGINATOR ID: 1 

सूचना ईवेंट हैंडलर कि MyEmitter के निर्माता हमेशा दूसरे बनाई उदाहरण के अंतर्गत आता है के भीतर की स्थापना की है के संस्करण के लिए LISTENER ID, जिससे कि यह प्रतीत कि उदाहरण है कि:

यहाँ कोड है हमेशा पहले आयोजन को पकड़ रहा है, और किसी कारण से पहले बनाए गए उदाहरण में कभी भी हैंडलर ट्रिगर नहीं हुआ है।

दो तथ्यों कि मुझे लगता है मैं सही ढंग से समझ संभालने हूँ:

  1. this ईवेंट हैंडलर में हमेशा उद्देश्य यह है कि घटना उत्सर्जित होना चाहिए।
  2. this कन्स्ट्रक्टर में हमेशा कन्स्ट्रक्टर द्वारा लौटने का ऑब्जेक्ट होना चाहिए (क्योंकि इसे new के साथ बुलाया जाता है)।

यदि ये दोनों सत्य हैं तो मुझे नहीं पता कि मैं और नहीं समझ रहा हूं कि परिणामस्वरूप व्यवहार में परिणाम क्या हैं।

एक और चीज ने मुझे इस बारे में सोचा: क्या किसी ईवेंट को हमेशा उसी ईवेंटइमीटर द्वारा "सुना" जाना चाहिए जो घटना को उत्सर्जित करता है? यही मैंने सोचा और निश्चित रूप से यह सबसे आम उपयोग मामला प्रतीत होता है। लेकिन अगर यह कोई प्रतिबंध नहीं है तो उदाहरण के लिए, बटन पर click ईवेंट अन्य सभी बटनों के लिए क्लिक हैंडलर ट्रिगर नहीं करता है?

उत्तर

6

समस्या यह है कि आप var self = this; का उपयोग नहीं कर रहे हैं ताकि self चरम पर एमिटर स्कोप को पिन किया जा सके। जब आप var को छोड़ देते हैं, तो जावास्क्रिप्ट वेरिएबल अप को स्कोप में उछाल देगा जब तक कि यह var के साथ घोषित मिलान करने वाला चर नाम न मिले। चूंकि आपने कभी एक घोषित नहीं किया है, self वैश्विक दायरे के लिए सभी तरह से होस्ट किया जाएगा, और इस प्रकार प्रत्येक उत्सर्जक एक ही संदर्भ के साथ बनाया जाएगा।

var self = this जोड़ना समस्या को हल करेगा। आप इन प्रकार के मुद्दों को पकड़ने के लिए use strict भी जोड़ सकते हैं, क्योंकि यह आपको var का उपयोग किए बिना एक चर घोषित करने की अनुमति नहीं देगा।

+0

विश्वास नहीं कर सकता कि मुझे कितना मूर्खतापूर्ण याद आया। किसी के पुराने कोड में इसे ठीक करने की कोशिश कर रहा था और बहुत गहराई से रास्ता देख रहा था। स्वयं के सामने var की कमी पूरी तरह से याद किया। धन्यवाद! – spectorar

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