È auspicabile un sistema di event-aware promettente?

5

Sono pienamente consapevole che Promises ed eventing sono entrambi modi di fare programmazione asincrona, e puoi scegliere uno per un determinato progetto. Tuttavia, in pratica, la base di codice con cui sto lavorando è ampia e usiamo molte librerie di terze parti che gestiscono l'asincronicità in modo diverso, quindi mescolare i due approcci insieme sono inevitabili (e spesso con effetti disastrosi).

Troppe volte ho visto persone lanciare un evento e poi fare più cose dopo di esso, mentre aspettavo che i gestori di eventi fossero completamente finiti. Sfortunatamente alcuni gestori di eventi inizieranno una catena di Promises, ma non è possibile per la fonte dell'evento sapere quando quella catena è stata risolta.

In teoria, il modo corretto di eseguire la programmazione asincrona con il solo eventing puro sarebbe stato per il gestore di eventi per generare un evento "event_x_completed" ma questo presuppone che esista sempre un solo gestore di eventi per l'originale "event_x" (a meno che vuoi che il codice diventi brutto Guarda l'esempio in basso). Nella programmazione dell'interfaccia utente, spesso non dovremmo preoccuparci di quanti ascoltatori ci sono. Per esempio. un'azione di un utente può generare un evento per attivare qualsiasi numero di componenti dell'interfaccia utente per aggiornarsi.

Inoltre, a seconda di come è fatto, potrebbe creare un accoppiamento stretto tra l'origine dell'evento e i listener di eventi, il che invalida in primo luogo un grande punto di forza nell'usare l'evento. Il mio progetto ha un'interfaccia utente complicata, quindi una fonte di eventi non può / non deve interessare il numero di gestori che ascoltano un evento.

Penso che sarebbe bello avere un sistema di eventing che verifica se ciascun gestore restituisce una Promessa (o un oggetto allora capace), e fire ("event_x") dovrebbe restituire Promise.all (all_promises_from_handlers) all'origine dell'evento.

Mi sono guardato intorno (forse non abbastanza difficile) e non vedo nessuno che parli di un sistema di eventi a conoscenza di Promise. Le persone hanno lo stesso problema e come sono gestite?

Modifica per esempio concreto:

Il mittente di "SAVE_PRESSED" non si cura di quanti gestori ci sono, si preoccupa solo che siano tutti completati. Penso che sarebbe immensamente utile essere in grado di fare questo:

function saveClicked() {
    saveButton.disable();
    EventManager.raise("SAVE_PRESSED").then(function() {
        saveButton.enable();
    });
}

Con un evento puro, ovviamente potremmo fare un loop su tutti gli ascoltatori e farlo invece:

function saveClicked() {
    saveButton.disable();
    var listeners = EventManager.getListeners("SAVE_PRESSED"); // array
    EventManager.raise("SAVE_PRESSED");
    EventManager.listen("SAVE_COMPLETED", function(listener_id) {
        var index = listeners.indexOf(listener_id);
        listeners = listeners.splice(index, 1);
        if (listeners.length === 0) {
            saveButton.enable();
            // AND -- unregister this function as a handler for SAVE_COMPLETED
        }
    });
}

Ciò che non mi piace di questo:

  • Il codice è più lungo e non è nemmeno completo e non ha una corretta gestione degli errori.
  • Dipende dagli ascoltatori che generano un evento "* _COMPLETED".
    • Se questo non è sempre vero o richiesto, ogni ascoltatore deve indicare se sono asincroni (genererà un evento COMPLETATO) o meno. Questa è una configurazione aggiuntiva da mantenere.
    • E invece di EventManager.getListeners ("SAVE_PRESSED"), chiamiamo EventManager.getAsyncListeners ("SAVE_PRESSED");
  • Questo codice / funzionalità dovrebbe essere fornito da EventManager
    • Se viene spostato in EventManager, gli eventi "* _COMPLETED" sono essenzialmente molto speciali .

In un sistema di eventi che promette di essere promettenti, i gestori possono dire al sistema che sono asincroni semplicemente restituendo un oggetto allora abile.

    
posta RonJRH 19.11.2016 - 02:07
fonte

2 risposte

2

Un sistema di event event promettente può aiutarti a creare soluzioni eleganti a problemi complessi. Tuttavia, penso che valga la pena scegliere un quadro esistente piuttosto che crearne uno tuo.

Il framework (JavaScript) che ho usato di più è Dojo e ha una robusta collezione di codice per la gestione degli eventi.

Include concatenare eventi come menzionato, poi, quando e tutti. tutto è bello perché aspetterà una serie di promesse da risolvere prima di procedere.

Ti suggerisco di scorrere alcune delle esercitazioni sul loro sito per vedere se servirà bene alle tue esigenze.

    
risposta data 22.11.2016 - 02:17
fonte
0

In theory, the proper way to do async programming with pure eventing alone would have been for the event handler to raise an "event_x_completed" event but that assumes that there is always exactly one event handler for the original "event_x". In UI programming, we can't make that assumption. E.g. one user action could raise an event to trigger any number of UI components to refresh themselves.

Er no. Non è assolutamente necessario presupporre che esista sempre esattamente un gestore di eventi.

Ci sono esattamente tanti gestori di eventi che vuoi che siano. Un gestore di eventi si registra in un elenco di gestori di quell'evento.

event_x_completed(x_id) mi dice esattamente quale evento è stato completato. Non è semplicemente un evento di tipo x ma era esattamente la x che stavo aspettando.

È confuso mescolare due paradigmi diversi, ma assicurati di sapere che li usi entrambi prima di presumere che siano completamente incompatibili.

    
risposta data 19.11.2016 - 20:52
fonte