La migliore strategia per segnalare i progressi nell'interfaccia utente - come dovrebbe avvenire la richiamata?

11

A volte l'utente avvia un'operazione tecnica estesa che richiede un po 'di tempo per essere eseguita. In questi casi, di solito è bello visualizzare una sorta di barra di avanzamento, insieme a informazioni su quale attività viene eseguita in questo momento.

Per evitare l'accoppiamento ravvicinato tra l'interfaccia utente e i livelli logici, solitamente è meglio che la comunicazione avvenga tramite una sorta di proxy. Ovvero, il back-end non dovrebbe manipolare i propri elementi dell'interfaccia utente, né addirittura interagire direttamente con il livello intermedio.

Ovviamente, ci deve essere qualche richiamo da qualche parte per fare in modo che funzioni. In genere l'ho implementato in due modi:

  1. Passa un oggetto mutabile al back-end e fai in modo che il back-end apporti le modifiche all'avanzamento. L'oggetto notifica al front-end quando si verifica una modifica.

  2. Passa una funzione call-back del modulo void f(ProgressObject) o ProgressObject -> unit richiamata dal back-end. In questo caso, il back-end costruisce ProgressObject ed è completamente passivo. Devo costruire un nuovo oggetto ogni volta che vuole segnalare il progresso, presumo.

Quali sono gli svantaggi e i vantaggi di questi metodi? C'è un metodo migliore concordato da usare? Ci sono diverse circostanze per il loro utilizzo?

Esistono tecniche completamente diverse per segnalare i progressi che ho trascurato?

    
posta GregRos 18.12.2015 - 16:47
fonte

5 risposte

8

Pass a mutable object to the back-end, and have the back-end make changes to it on progress. The object notifies the front-end when a change occurs.

È difficile bilanciare l'efficienza se il backend notifica a questo riguardo. Senza preoccuparti potresti scoprire che incrementare i tuoi progressi finisce per raddoppiare o triplicare il tempo necessario per completare l'operazione se stai mirando a un aggiornamento progressivo senza intoppi.

Pass a call-back function of the form void f(ProgressObject) or ProgressObject -> unit that the back-end invokes. In this case, the back-end constructs the ProgressObject and it's completely passive. It must construct a new object every time it wants to report progress, I assume.

Non trovo la differenza qui tanto.

Are there completely different techniques of reporting progress that I've overlooked?

Sondare dal front-end in un thread separato con incrementi atomici nel back-end. Il polling ha senso qui poiché è per un'operazione che termina in un periodo finito e la probabilità che il frontend raccolga i cambiamenti di stato è alta, specialmente se si punta ad una barra di progressione liscia come la seta. Potresti considerare le variabili di condizione se non ti piace l'idea di eseguire il polling dal thread di frontend, ma in tal caso potresti voler evitare di notificare ogni singolo incremento progressivo della barra di avanzamento.

    
risposta data 24.12.2015 - 22:20
fonte
1

Questa è la differenza tra un meccanismo di notifica push e pull .

L'oggetto mutabile ( pull ) dovrà essere interrogato ripetutamente dall'interfaccia utente e sincronizzato se ci si aspetta che l'attività di back-end venga eseguita in un thread background / worker.

Il callback ( push ) creerà solo il lavoro per l'interfaccia utente quando qualcosa cambia effettivamente. Molti framework UI hanno anche un invokeOnUIThread callable da un thread di lavoro per fare in modo che un pezzo di codice venga eseguito sul thread dell'interfaccia utente, in modo che tu possa effettivamente apportare le modifiche senza calpestare i rischi legati ai thread. (gioco di parole)

In generale, le notifiche push sono preferibili perché funzionano solo quando è necessario lavorare.

    
risposta data 18.12.2015 - 16:54
fonte
0

Uso websocket con AngularJS. Quando il front-end riceve un messaggio, lo visualizza in un'area di messaggio designata che si dissolve in bianco dopo alcuni secondi. Sul back-end pubblicherò solo messaggi di stato in una coda di messaggi. Invio solo testo, ma non c'è motivo per cui non potrei inviare un oggetto status con valori come percentuale di completamento o velocità di trasferimento.

    
risposta data 18.12.2015 - 19:05
fonte
0

Hai menzionato i tuoi "due modi" come se fossero concetti separati, ma voglio riprenderlo un po '.

  1. Pass a mutable object to the back-end, and have the back-end make changes to it on progress. The object notifies the front-end when a change occurs.

Hai già detto che vuoi evitare l'accoppiamento ravvicinato tra l'interfaccia utente e la logica, quindi posso tranquillamente supporre che questo "oggetto mutevole" che stai passando sia in realtà un'implementazione di una particolare interfaccia che è definita nella logica modulo. In quanto tale, questo è semplicemente un altro modo di passare una richiamata nel processo che viene periodicamente chiamata con informazioni sul progresso.

Per quanto riguarda i vantaggi e gli svantaggi ...

Uno svantaggio per method (1) è che la classe che implementa l'interfaccia può farlo solo una volta. (Se vuoi eseguire lavori diversi con invocazioni diverse, avrai bisogno di un'istruzione switch o del pattern visitor.) Con method (2), lo stesso oggetto può usare un callback differente per ogni invocazione del codice backend senza la necessità di un interruttore.

Un punto di forza per method (1) è che è molto più semplice avere più metodi sull'interfaccia che trattare i callback multipli di metodo (2) o il callback singolo con un'istruzione switch per più contesti.

    
risposta data 20.12.2017 - 17:19
fonte
-2

Le tecniche che puoi usare possono essere molto diverse.

Cerco di capire con uno scenario diverso

  • Richiesta di db
  • scarica il file

Una semplice richiesta di accesso a db (che significa rispondere da db con un elemt) non ha bisogno di un avanzamento del report, ma è sempre possibile attivare il thread dell'interfaccia utente in un task separato ex. async o backgroundworker, qui hai solo bisogno di una callback per il risultato.

Ma cosa succede se chiedi per vedere tutto il tuo inventario con 1mln elemento? Questa query dovrebbe richiedere diversi minuti per essere completata, quindi in questo caso è necessario implementare i progressi del perport nella logica di business nell'elemento del modulo / elementi, quindi è possibile aggiornare l'interfaccia utente e l'opzione può annullare la richiamata.

Lo stesso caso per il download di file. È sempre possibile implementare qui la richiamata di avanzamento nel byte di byte di forma e tenere il controllo di tutta la comunicazione su http è molto comune.

Per quanto riguarda il mio approccio personale, implemento la mia logica di avanzamento del business solo per i miei clienti, evitando di condividere altri oggetti con end-point.

    
risposta data 18.12.2015 - 23:36
fonte

Leggi altre domande sui tag