javascript Perché il ciclo di eventi di Jquery viene interrotto in caso di eccezione



jquery on click (1)

Questo succede a causa di questo ciclo preso dall'origine .dispatch :

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

Come puoi vedere, non ci sono tentativi / .apply .

È così che è stato per anni, anni e anni .

Anche se volessero, cambiandolo ora si romperà troppo il codice esistente. Ricorda, molte cose in jQuery che sembrano arbitrarie ora sono nate in un altro momento.

Ovviamente puoi "aggiustarlo" nel tuo codice (avvolgendolo in un try / catch con un messaggio di errore), ma sorprenderesti praticamente tutti gli altri.

Dopo un comportamento strano della nostra applicazione (usando strophe XMPP e jquery), abbiamo scoperto che il ciclo di eventi jquery è sincrono e non cattura l'eccezione.

Significa che se il primo gestore di eventi solleva un'eccezione, la seconda non viene mai chiamata.

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

Ci aspettavamo di vedere due output, ma il secondo: "listener onBar" non è mai stato visualizzato.

Vedi il codice JQuery, nella funzione "trigger", non esiste un pattern try / catch durante il ciclo dei gestori.

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)

Siamo stati sorpresi da questa implementazione.

In puro javascript, tutti i gestori vengono chiamati anche se uno di essi si blocca : http://jsfiddle.net/bamthomas/kgS7A/2/ .

Qualcuno sa perché il team di JQuery non consente l'esecuzione del gestore successivo anche se il precedente si è bloccato? Perché le eccezioni non vengono catturate?

Perché non hanno usato il gestore di eventi javascript?





javascript-events