Un ascoltatore di eventi dovrebbe essere chiamato se è collegato dopo che l'evento è già stato attivato?

8

Si dovrebbe chiamare un ascoltatore di eventi se è allegato dopo che l'evento è già stato attivato? Cosa succede se l'evento verrà attivato una sola volta?

Il primo esempio che viene in mente è l'evento ready in jQuery. Il seguente frammento, una volta valutato dopo il caricamento della pagina, chiamerà comunque il callback:

$(document).ready(function () {
    console.log("Works.");
});

L'alternativa a questo comportamento potrebbe essere un flag che viene impostato quando la pagina viene caricata, costringendo il consumatore dell'API a verificare se l'evento è già accaduto e agire di conseguenza:

if (document.readyState == "complete") {
    console.log("Works.");
} else {
    $(document).ready(function () {
        console.log("Works.");
    });
}

Sebbene l'esempio sopra riportato sia nel contesto di un caricamento di una pagina web in cui qualsiasi cosa (di solito) deve accadere dopo che la pagina è stata caricata completamente, gli stessi argomenti potrebbero essere fatti per qualsiasi singolo componente in un'applicazione, che ha " singleton "eventi ( load , start , end , ecc.). Un esempio di un singolo componente potrebbe essere una mappa con un evento load che viene attivato per specificare che la mappa che è stata caricata :

map.on("load", function () {
    console.log("The map has loaded.");
});

L'esempio precedente proviene dall'API ArcGIS per JavaScript, in cui quell'evento viene generato una sola volta e se un utente "attende" che la mappa venga caricata dopo che la mappa è già stata caricata, il listener non verrà mai chiamato. Il risultato desiderato richiede di controllare lo stato della mappa prima che l'ascoltatore sia allegato:

if (map.loaded) {
    console.log("The map has loaded.");
} else {
    map.on("load", function () {
        console.log("The map has loaded.");
    });
}

Quale comportamento è corretto, richiedendo al consumatore di verificare se un evento è già stato attivato o chiama sempre il callback?

    
posta Whymarrh 29.11.2014 - 17:46
fonte

2 risposte

19

Ciò dipende dal fatto che si tratti realmente di un evento o di una notifica di stato (che è ciò che è pronto). Se si tratta di un evento, allora non devi dire all'ascoltatore di tutti gli eventi precedenti. Se si tratta di notifiche di stato, le comunichi immediatamente dopo che si sono abbonati e ti trovi nello stato specificato.

La parte difficile sarà dove può essere uno stato o un evento, a seconda di come la si guarda - nel peggiore dei casi, ciò è spiegato dal documento. Nel migliore dei casi scegli un buon nome che ti chiarisca cosa intendi.

    
risposta data 29.11.2014 - 18:10
fonte
5

In generale, no .

Gli ascoltatori di eventi dovrebbero non essere chiamati se sono collegati dopo che l'evento è già stato attivato. "Posticipa, perdi."

Ci sono alcune importanti eccezioni. $(document).ready() è forse l'esempio perfetto: un evento precedente al quale l'intero contesto di valutazione non è stabilito in modo affidabile o completo e che funge da indicatore di "elaborazione completa inizia qui".

Se tuttavia imposti la regola che un gestore di eventi debba essere attivato anche se è installato e / o attivato dopo che si è verificato l'evento, hai dichiarato che tutti gli eventi devono o devono essere memorizzati nel buffer dall'inizio alla fine del programma eseguito, per ogni evento immaginabile. Altrimenti, potrebbero esserci gestori di eventi stabiliti in qualche evento, da qualche parte lungo la strada, che non si dispone di informazioni sufficienti per sapere se è necessario licenziare quando è stabilito. Ciò significa che devi strumentare ogni possibile fonte di eventi e bufferare infinitamente anche ognuno di essi. Questo richiede l'elaborazione dell'evento dalla valutazione pigra (e tutti i suoi benefici in termini di prestazioni) fino a la valutazione leale e su qualsiasi cosa si trovi all'estremità dello spettro. Valutazione frenetica basata su catastrofiche ipotesi su quali eventi potrebbero dover essere gestiti successivamente?

Gli eventi tendono ad essere transitori e numerosi. L'impostazione di regole che richiedono a ciascuno di essere memorizzate, senza limiti, sulla possibilità che vengano eventualmente sfruttate - è il suicidio per prestazioni. Inoltre, non c'è un grande requisito per farlo, dal momento che i gestori possono essere generalmente stabiliti all'inizio della vita del programma.

Le eccezioni alla regola sono casi limite: carichi di documenti o di sottosistema, ad esempio, eventi essenziali, unici, importanti che non sono altrimenti catturabili o gestibili. Questo è molto vicino ai tuoi eventi "singleton". Un altro gruppo che potrebbe richiedere una gestione speciale sono errori significativi, eventi di sicurezza o cambiamenti di stato che hanno una necessità eccezionale di essere segnalati anche se non ci sono abbonati alla bandiera nel momento in cui si è verificato l'evento.

Un'ultima nota: un evento "pronto" è leggermente diverso da un evento "carico". Anche se spesso non sono chiaramente distinti (ad esempio, onload di HTML e% co_de di jQuery considerati logicamente molto simili), ed entrambi segnalano la disponibilità di una risorsa o di un ambiente di elaborazione, ma non sono esattamente gli stessi. Il caricamento (o il completamento di esso) è un vero evento - qualcosa segnalato dall'infrastruttura al consumatore. La prontezza, tuttavia, è più il rendezvous dell'infrastruttura che carica la risorsa / l'ambiente e il consumatore è in procinto di consumare / sfruttare tale disponibilità. La prontezza viene dopo il carico ed è uno di quegli eventi speciali designati / punti di coordinamento che devono essere trattati come accodabili perché non è possibile catturarli in altro modo. Il fatto che ci siano alcuni casi molto speciali, tuttavia, non significa che ogni evento dovrebbe essere licenziabile a posteriori .

    
risposta data 04.12.2014 - 00:23
fonte

Leggi altre domande sui tag