2014-05-13 14 views
29

Nella chat di Facebook sull'architettura Flux, Jing menziona at 12:17 che il dispatcher impone che nessuna azione può essere inviata finché l'azione corrente non viene completamente elaborata dai negozi.Come gestite le operazioni dell'archivio asincrono con Flux?

https://img.youtube.com/vi/nYkdrAPrdcw/0.jpg

Il dispatcher qui è il pezzo principale che impone che non ci sono effetti a cascata; una volta che un'azione è entrata nel negozio, non è possibile inserirne un'altra finché i negozi non hanno completato l'elaborazione.

La mia domanda, allora, è come si fa a trattare correttamente con esecuzione prolungata operazioni asincrone che potrebbe essere dato il via dal negozio (ad esempio, una richiesta Ajax, o trattare con qualche altro API asincrona esterno) -anything che blocca il completamento del dispiegamento dell'azione (ad esempio, in attesa di risolvere una promessa con il risultato di una richiesta Ajax) potrebbe bloccare le azioni generate dall'interfaccia utente dall'essere spedite.

risposta

30

A mio avviso, le azioni asincrone che fanno affidamento su Ajax, ecc., Non devono impedire l'invio dell'azione a tutti i sottoscrittori.

Dovrete un'azione separata per l'azione dell'utente, come TODO_UPDATE_TEXT nell'esempio TodoMVC e uno che viene chiamato quando il server restituisce, qualcosa come TODO_UPDATE_TEXT_COMPLETED (o forse solo qualcosa di più generico come TODO_UPDATE_COMPLETED che contiene una nuova copia di gli ultimi attributi).

Nei casi in cui si desidera eseguire aggiornamenti ottimistici per mostrare all'utente gli effetti della modifica immediatamente, è possibile aggiornare immediatamente l'archivio in risposta all'azione dell'utente (e quindi di nuovo quando il server restituisce i dati autorevoli) . Se si desidera attendere sul server, è possibile fare in modo che il negozio si aggiorni da solo in risposta alle azioni attivate dal server.

+3

Supponiamo che l'aggiornamento non riesca e che il server restituisca un messaggio di errore che si desidera visualizzare. Nel gestore TODO_UPDATE_FAILED, salvi il messaggio di errore nel negozio di cose da fare? – scttnlsn

+3

@scttnlsn È necessario chiedersi se il messaggio di errore deve essere memorizzato in TodoStore. In caso contrario, come suggerimento, è necessario creare un archivio dati separato per i messaggi di errore che a loro volta verranno utilizzati dai componenti che gestiscono i messaggi di errore (ad esempio un componente del messaggio di avviso). – Spoike

+0

Rompere un'attività con più azioni può rovinare le cose, se due o più di tali compiti si intrecciano tra loro, qual è la migliore pratica per evitarlo? –

2

Vedere l'implementazione di ciò che Sophie spiega in this fluxxor example di gestione dei dati asincroni. Un punto negativo è che seguendo questo approccio, ogni interazione dell'utente richiede tre azioni (trigger, success e fail) ma forse non tutte le interazioni dell'utente richiedono questo approccio ottimistico.

La parte importante è nell'azione:

loadBuzz: function() { 
    this.dispatch(constants.LOAD_BUZZ); 

    BuzzwordClient.load(function(words) { 
    this.dispatch(constants.LOAD_BUZZ_SUCCESS, {words: words}); 
    }.bind(this), function(error) { 
    this.dispatch(constants.LOAD_BUZZ_FAIL, {error: error}); 
    }.bind(this)); 
    }, 

BinaryMuse (creatore fluxxor) invia l'azione LOAD_BUZZ e poi innesca la richiesta asincrona con il successo e non riescono funzioni, dove dispacci il successo o fallire l'azione. I negozi possono ascoltare l'azione LOAD_BUZZ per un aggiornamento ottimistico o visualizzare un'icona di caricamento svg e quindi ascoltare le azioni di successo e di errore per una notifica finale di successo o errore (oltre a salvare il BUZZWORD nel negozio).

onLoadBuzz: function() { 
    this.loading = true; 
    this.emit("change"); 
}, 

onLoadBuzzSuccess: function(payload) { 
    this.loading = false; 
    this.error = null; 

    this.words = payload.words.reduce(function(acc, word) { 
    var clientId = _.uniqueId(); 
    acc[clientId] = {id: clientId, word: word, status: "OK"}; 
    return acc; 
    }, {}); 
    this.emit("change"); 
}, 

penso come Sophie che le richieste Ajax non dovrebbero bloccare l'azione di essere spedito, perché questo sarebbe più come una richiesta sincrona al server e la capacità di risposta della pagina potrebbero essere interessate.

Problemi correlati