2015-09-01 22 views
6

Sto facendo un XMLHttpRequest ogni secondo su un server, il server risponderà con nuovi messaggi. Per chiamare il XMLHttpRequest ogni secondo, utilizzo la funzione setInterval() all'interno di un numero SharedWorker.SetInterval() è una funzione asincrona?

Tuttavia, dal momento che sto facendo una richiesta al secondo, vorrei sapere se setInterval() è asincrono o no? Ad esempio, se una richiesta di XMLHttpRequest impiega 3 secondi per terminare "a causa di un ritardo", avrò 3 richieste in corso allo stesso tempo o setInterval() attendere fino al completamento della prima richiesta prima di attendere 1 secondo e inviare un altro richiesta?

Ecco il mio codice

function checkQueue(url) 
{ 
    var xhr = new XMLHttpRequest(); 
    xhr.addEventListener("load", reqListener); 
    xhr.open('GET', url, true); 
    xhr.send(); 
} 


function reqListener() 
{ 
    var queue = JSON.parse(this.responseText); 
    notifyAllPorts(queue); 
    console.log(this.responseText); 
} 


setInterval(
    function() { 
     checkQueue('/add-ons/icws/push.php') 
    } 
, 1000); 
+0

È asincrono, ma non si avranno 3 richieste in contemporanea, poiché l'intervallo di funzione è 1 secondo. La funzione fornita verrà eseguita ogni secondo, indipendentemente da cosa. – MinusFour

+0

@MinusFour allora avrò almeno 2 in contemporanea. Se il server impiega 10 secondi per rispondere, la richiesta continuerà a venire. Come posso evitare che ciò accada? –

+1

Si potrebbe fare con una promessa, posso fornire una risposta per questo se la domanda è come interrompere una promessa. – MinusFour

risposta

1

Come sottolineato, non aspetterà che la richiesta venga eseguita. Ecco un modo all'intervallo una promessa:

function checkQueue(url, cb) { 
    var xhr = new XMLHttpRequest(); 
    xhr.addEventListener("loadend", cb); 
     xhr.addEventListener("load", reqListener); 
    xhr.open('GET', url, true); 
    xhr.send(); 
} 

function reqListener() 
{ 
    var queue = JSON.parse(this.responseText); 
    notifyAllPorts(queue); 
    console.log(this.responseText); 
} 

var promise = Promise.resolve(true); 

setInterval(function() { 
    promise = promise.then(function() { 
     return new Promise(function (resolve) { 
      checkQueue(yourUrlHere, resolve); 
     }); 
    }); 
}, 1000); 

Manterrà su come aggiungere le richieste di fare ogni secondo, ma ritarderà se stessa se si va oltre 1 secondo.

+0

per assicurarmi di seguirti qui. Quindi, se una richiesta impiega 10 secondi, creerà una coda con le richieste e una volta terminata, inizierà a eseguire le richieste che sono in coda fino a quando non viene messa a tacere? –

+0

Se una richiesta impiega 10 secondi, questo farebbe in coda 8-9 richieste da fare, ma continuerà a sparare solo dopo che l'ultimo è stato completato. In altre parole, in un'ora, accoderà 3600 petizioni. Se le petizioni durano tutti 1 secondo, allora tutte le 3600 petizioni saranno fatte. Se una petizione impiega più di 1 secondo, ritarderà la prossima petizione in coda, finché non avrà terminato, portando a meno di 3600 petizioni. – MinusFour

+0

Ho twittato il tuo codice un po 'mentre sto sperimentando un problema in cui questo codice generava una nuova connessione TCP al secondo. non riutilizza una connessione TCP aperta. Si prega di dare un'occhiata a un'altra domanda che ho postato http://stackoverflow.com/questions/32505128/how-to-make-xmlhttprequest-reuse-a-tcp-connection grazie per il vostro aiuto :) –

1

setInterval semplicemente accoda il codice da eseguire una volta lo stack di chiamate corrente è terminato l'esecuzione. Questo può essere utile per alcune cose.

Quindi sì, è asincrono in quanto interrompe il flusso sincrono, ma in realtà non verrà eseguito contemporaneamente/su un thread separato. Se il tuo obiettivo è l'elaborazione in background, dai un'occhiata ai webworkers.

Quindi, indipendentemente di come server di tempo molto più prende chiederà ogni secondo come per il vostro codice è impostato per 1000

+0

Significa che "setTimeout" eseguirà una funzione 1 secondo dopo la fine della funzione, mentre "setInterval" verrà eseguito indipendentemente dal risultato della funzione? –

2

Sì, si incorrerà in problemi. setInterval andrà via come un orologio, indipendentemente dallo stato delle vostre richieste.

si sta meglio-off di iniziare un timer con un colpo setTimeout al completamento di ogni richiesta ... quindi:

function checkQueue(url) 
{ 
    var xhr = new XMLHttpRequest(); 
    xhr.addEventListener("load", reqListener); 
    xhr.open('GET', url, true); 
    xhr.send(); 
} 


function reqListener() 
{ 
    var queue = JSON.parse(this.responseText); 
    notifyAllPorts(queue); 
    console.log(this.responseText); 
    setTimeout(
     function() { 
      checkQueue('/add-ons/icws/push.php') 
     }, 1000); 
} 


checkQueue('/add-ons/icws/push.php') 
+0

grazie per la risposta. Quindi cosa farai esattamente codice? come garantisce che una richiesta possa iniziare solo che una di esse sia completata? –

+0

... perché si avvia un timer unico una volta che siamo sicuri che la richiesta precedente è stata completata (ad esempio dopo l'evento 'load' di XMLHttpRequest ... viene richiamata la richiamata, quindi la richiesta viene eseguita). Ciò significa che una volta che la richiesta precedente è ** finita **, allora aspettiamo un secondo prima di riavviare. Esattamente quello che volevi, no? – spender

+0

Vedo. Quindi questo codice garantirà che nessuna richiesta è trigger a meno che quella esistente non sia completata. Questo codice si riconnetterà se la connessione tra il server e il lavoratore cade? –

0

sì setTimeout setInterval & sono asincrono, ma non si fa una spinta, fai un pull, se vuoi una richiesta push leggi di prese web

+0

Nel mio caso non posso usare websockets perché non utilizzo i frame. il mio sito viene ricaricato tutto il tempo. –