2014-04-10 7 views
8

हमारे आवेदन (स्ट्रॉफ़ एक्सएमपीपी और jQuery) का अजीब व्यवहार करने के बाद, हमने पाया है कि jquery event loop तुल्यकालिक है और अपवाद नहीं पकड़ता है।अपवाद पर Jquery इवेंट लूप क्यों बाधित है

इसका मतलब है कि यदि पहला ईवेंट हैंडलर अपवाद उठाता है, तो दूसरा को कभी नहीं कहा जाता है।

$(document).ready(function() { 
    $(document).bind('foo', onFoo); 
    $(document).bind('bar', onBar); 

    $(document).trigger('foo'); 
    $(document).trigger('bar'); 
}); 

function onFoo(e) { 
    console.log('listener onFoo'); 
    throw 'fail onFoo'; 
} 

function onBar(e) { 
    console.log('listener onBar'); // not called 
} 

हमें दो आउटपुट देखने की उम्मीद है, लेकिन दूसरा: "श्रोता ऑनबार" कभी प्रदर्शित नहीं हुआ था।

"ट्रिगर" फ़ंक्शन में JQuery कोड देखें, हैंडलर के लूप के दौरान कोई प्रयास/पकड़ पैटर्न नहीं है।

while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { 
    event.type = i > 1 ? 
     bubbleType : 
     special.bindType || type; 

    // jQuery handler 
    handle = (jQuery._data(cur, "events") || {})[ event.type ] && jQuery._data(cur, "handle"); 
    if (handle) { 
     handle.apply(cur, data); 
    } 
... (line 4998 in JQuery 1.10.2) 

हम इस कार्यान्वयन से आश्चर्यचकित हैं।

शुद्ध जावास्क्रिप्ट में, सभी हैंडलर को बुलाया जाता है भले ही उनमें से एक क्रैश हो: http://jsfiddle.net/bamthomas/kgS7A/2/

क्या कोई जानता है कि क्यों JQuery टीम अगले हैंडलर के निष्पादन की अनुमति नहीं देती है, भले ही पिछला एक क्रैश हो जाए? अपवाद क्यों नहीं पकड़े जाते हैं?

उन्होंने जावास्क्रिप्ट ईवेंट हैंडलर का उपयोग क्यों नहीं किया?

+0

"jQuery क्यों अपवाद नहीं पकड़ता है?" - सबसे अधिक संभावना है क्योंकि कोई भी नहीं सोचा कि यह एक समस्या हो सकती है। आपका गिथब रेपो को पुल अनुरोध भेजने के लिए आपका स्वागत है। –

+0

यदि आपका ईवेंट हैंडलर फेंक सकता है, तो अपवाद को पकड़ना आपकी ज़िम्मेदारी है। आप क्यों उम्मीद करेंगे (या यहां तक ​​कि चाहते हैं) कि 'ट्रिगर' ऐसा करता है? – Tomalak

+0

जितना अधिक खोज कि jQuery को अपवाद नहीं मिलते हैं, उपयोगी हो सकता है, मुझे नहीं लगता कि इस प्रश्न का उत्तरदायी उत्तर दिया जा सकता है ... –

उत्तर

2

यह this loop taken from the .dispatch source की वजह से होता है:

while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) { 

    // Triggered event must either 1) have no namespace, or 
    // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). 
    if (!event.namespace_re || event.namespace_re.test(handleObj.namespace)) { 

     event.handleObj = handleObj; 
     event.data = handleObj.data; 

     ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler) 
     .apply(matched.elem, args); 

     if (ret !== undefined) { 
      if ((event.result = ret) === false) { 
       event.preventDefault(); 
       event.stopPropagation(); 
      } 
     } 
} 

आप देख सकते हैं, वहाँ कोई ट्राई/कैच के आसपास है .apply

इस तरह से यह years और years and years के लिए किया गया है।

भले ही वे चाहते थे, अब इसे बदलना बहुत अधिक मौजूदा कोड तोड़ देगा। याद रखें, jQuery में बहुत सी चीजें जो मनमानी लगती हैं अब किसी अन्य समय पैदा हुई थीं।

आप निश्चित रूप से इसे अपने स्वयं के कोड में ठीक कर सकते हैं (इसे त्रुटि संदेश के साथ प्रयास/पकड़ में लपेटें), लेकिन आप सब कुछ और आश्चर्यचकित होंगे।

+0

"इसे बदलना अब बहुत अधिक मौजूदा कोड तोड़ देगा।" - क्या आप एक उदाहरण प्रदान कर सकते हैं? –

+0

@JanDvorak हां। जंगली में बहुत सारे कोड हैं जिन्हें मशहूर 'फेंक दिया गया jQuery तब तक काम करता है जब तक यह काम नहीं करता'। हम जो जानते हैं उसके लिए, किसी के पास ओपी के समान कोड हो सकता है और वे अन्य श्रोताओं को दौड़ने से रोकने के लिए फेंकने का उपयोग कर रहे हैं। –

+0

ईडब्ल्यू। वह लक्ष्य हासिल करने का एक भयानक तरीका है। फिर भी - अच्छा बिंदु, धन्यवाद। –

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