2011-12-30 15 views
11

Per una semplice webapp che deve aggiornare parti dei dati presentate all'utente in intervalli prestabiliti, ci sono dei lati negativi semplicemente usando setInterval() per ottenere un json da un endpoint invece di utilizzando un quadro di sondaggio adeguato?Uso di setInterval() per eseguire il polling continuo semplicistico

Per l'esempio, diciamo che sto aggiornando lo stato di un processo di elaborazione ogni 5 secondi.

+6

userei 'setTimeout' e sempre chiamarlo quando è stata ricevuta la risposta precedente. In tal modo si evita la congestione o l'impilamento delle funzioni o qualsiasi altra cosa si voglia chiamare. –

+0

L'ho fatto proprio come ha detto @FelixKling e funziona come un fascino. Provalo! – Alfabravo

+0

Fantastico! Posso @FelixKling, potresti postare la risposta come risposta e accetterò? – Sologoub

risposta

25

Dal mio commento:

userei setTimeout[docs] e sempre chiamarlo quando è stata ricevuta la risposta precedente. In tal modo si evita la congestione o l'impilamento delle funzioni o qualsiasi altra cosa si voglia chiamare, nel caso in cui una richiesta/risposta richieda più tempo dell'intervallo.

Quindi qualcosa di simile:

function refresh() { 
    // make Ajax call here, inside the callback call: 
    setTimeout(refresh, 5000); 
    // ... 
} 

// initial call, or just call refresh directly 
setTimeout(refresh, 5000); 
+3

Una bella analisi qui sul perché evitare 'setInterval' è una buona idea: http://weblogs.asp.net/bleroy/archive/2009/05/14/setinterval-is-moderately-evil.aspx –

+0

dovremmo usare' setTimeout (refresh, 5000); 'due volte? Intendo uno dopo la chiamata iniziale e poi di nuovo nella funzione chiamata? – David

1

So che questa è una vecchia questione, ma ci siamo imbattuti su di esso, e nel modo di fare le cose StackOverflow ho pensato che avrei potuto migliorarlo. Potresti prendere in considerazione una soluzione simile a what's described here che è nota come polling lungo. O un'altra soluzione è WebSockets (una delle migliori implementazioni di websocket con l'obiettivo primario di lavorare su tutti i browser) socket.io.

La prima soluzione viene sostanzialmente riepilogata quando si invia una singola richiesta AJAX e si attende una risposta prima di inviarne un'altra, quindi una volta inviata la risposta, accodare la query successiva.

Nel frattempo, sul backend non si restituisce una risposta finché lo stato non cambia. Quindi, nel tuo scenario, dovresti utilizzare un ciclo while che continuerà fino a quando lo stato non cambierà, quindi restituirai lo stato modificato alla pagina. Mi piace davvero questa soluzione. Come indica la risposta sopra riportata, questo è ciò che Facebook fa (o almeno ha fatto in passato).

socket.io è fondamentalmente il jQuery di Websockets, in modo tale che qualsiasi browser in cui si trovano gli utenti sia in grado di stabilire una connessione socket in grado di inviare dati alla pagina (senza eseguire il polling). Questo è più vicino alle notifiche istantanee di Blackberry, che - se stai per un istante, è la soluzione migliore.

+0

Sebbene socket.io potrebbe essere buono, non è la soluzione per i websocket una soluzione tra tante. Tutti (quasi) bravi a modo loro e si potrebbero prendere in considerazione diversi quadri a seconda del compito da risolvere. – Uffe

+0

Incurante, aggiornato per riflettere l'intenzione di citare socket.io – th3byrdm4n

1

Si può fare proprio come questo:

var i = 0, loop_length = 50, loop_speed = 100; 

function loop(){ 
    i+= 1; 
    /* Here is your code. Balabala...*/ 
    if (i===loop_length) clearInterval(handler); 
} 

var handler = setInterval(loop, loop_speed); 
2

Un semplice non bloccante-funzione di sondaggio può essere implementato in recenti browser utilizzando promesse:

var sleep = time => new Promise(resolve => setTimeout(resolve, time)) 
var poll = (promiseFn, time) => promiseFn().then(
      sleep(time).then(() => poll(promiseFn, time))) 

// Greet the World every second 
poll(() => new Promise(() => console.log('Hello World!')), 1000) 
+0

buono. lavori. Se dopo un po 'di tempo decido di interrompere l'esecuzione con un clic, ad esempio, come potrei farlo, per favore? – Marcel

+0

@Marcel Grazie. La risposta breve è che ciò non è possibile (https://stackoverflow.com/a/29479435/1054423). – bschlueter

Problemi correlati