2011-01-17 10 views
11

Ho molte chiamate AJAX asincrone i cui risultati verranno elaborati. Non importa in che ordine avviene l'elaborazione, ma i risultati devono essere elaborati uno alla volta. Quindi mi piacerebbe fare semplicemente le mie chiamate AJAX e tutti loro inseriscono i loro risultati in un'unica coda. Quella coda dovrebbe quindi essere elaborata su un singolo thread. In questo modo i risultati vengono elaborati uno alla volta il prima possibile.Coda thread-safe in Javascript o jQuery

Qual è il modo migliore per farlo? Sto usando jQuery, così felice di sfruttare tutte le strutture che fornisce per questo.

risposta

25

asincrona non vuol dire 'più thread. Pensa a molti eventi di clic che vengono attivati ​​in una riga, prima che venga elaborato il primo gestore di clic. È possibile gestire una sola azione alla volta e le altre attenderanno l'esecuzione.

I linguaggi basati sugli eventi come Javascript funzionano sulla base di una coda. Javascript in background ha essenzialmente una coda gigantesca a cui gli eventi e le risposte asincrone vengono spinti. Una volta completato un particolare pezzo di elaborazione, viene elaborato l'elemento successivo dalla coda.

Queste code sono talvolta denominate "Runloops". Javascript girerà in un ciclo infinito, recuperando un evento dalla coda, elaborandolo e ritornando in coda per un altro lavoro.

Il multithreading può essere ottenuto nelle versioni (più recenti) di Javascript utilizzando Web Workers, ma queste sono esplicitamente attivate. Guardali se sei interessato.

Per rispondere alla domanda, è sufficiente associare un callback alla richiesta asincrona e l'elaborazione verrà completata anche se viene restituita un'altra risposta a metà. L'altra risposta "aspetta" finché non viene gestito l'evento corrente.

+6

Penso che tutti stiano complicando la domanda perché ha usato la parola "discussioni". Credo che OP significhi semplicemente che ha bisogno che ogni callback sia completato prima che inizi il prossimo. Sto assumendo perché jQuery è coinvolto questo perché un certo tipo di animazione si sta verificando, che userà i timer e quindi apparirà multi-thread (due callback possono sembrare in esecuzione contemporaneamente). – beeglebug

+0

@beeglebug - Non credo che tu abbia ragione. L'OP afferma esplicitamente "Non importa in che ordine avviene l'elaborazione". È un'idea sbagliata comune che asincrono significhi multithreading e credo che l'OP abbia avuto questa stessa impressione. –

+0

@Josh Smeaton - Probabilmente, ma potremmo farlo con OP se stesso tornando indietro e facendo luce. Tutto dipende dal fatto che "elaborazione" significhi crunch di numeri grezzi o qualcosa di più basato sull'interfaccia utente. E con jQuery coinvolto (e guardando la storia delle domande di OP) penso che sia l'interfaccia utente/l'animazione. – beeglebug

5

Se la tua unica preoccupazione è il browser (dal momento che menzioni jQuery, presumo sia vero), dovresti sapere che Javascript is single-threaded in browsers.

+2

Wow, non ero a conoscenza di questo e sembra strano ... quindi posso fare 100 richieste AJAX, e sembra che queste richieste siano asincrone e su thread separati, e le funzioni di callback saranno chiamate una alla volta ? –

+0

Credo sia corretto. –

+0

@dorktitude - In realtà, JavaScript è ora multi-threaded, grazie a WebWorkers: https://developer.mozilla.org/En/Using_web_workers – jmort253

0

Il modo più semplice sarebbe implementare il proprio sistema di code per i callback (utilizzando push/pop per emulare uno stack).

Ogni volta che viene restituita una richiesta asincrona, aggiungere i dati alla fine di un array e attivare una sorta di comando queue.process(), che gestirà il primo elemento dell'array.

Infine, aggiungi qualcosa come if(alreadyRunning) { return; } all'inizio di quella funzione per impedirne l'esecuzione in più di una volta e hai la tua coda con thread singolo.

edit: codice rimosso, alcune persone sono state sempre appeso su di esso, invece di domanda originale

+0

L'unica volta che ci saranno più elementi nella tua coda è se 'this.handler (item)' inserisce un altro workitem nello stack. Non è assolutamente necessario, poiché la maggior parte delle chiamate asincrone è in grado di accettare i callback al completamento. –

+0

Ho pensato che l'idea fosse che qualche codice esterno avrebbe attivato le chiamate ajax e usava 'queue.add' come callback. In questo modo i dati di ritorno sarebbero stati aggiunti alla coda e se un secondo pezzo di dati fosse stato restituito mentre il primo era in elaborazione, sarebbe stato aggiunto alla coda per essere elaborato una volta che il primo era stato completato. – beeglebug

+0

Impossibile. Un'altra restituzione di dati NON può essere eseguita mentre il primo è ancora in elaborazione. Attenderà fino a quando l'unico thread diventa "gratuito" per eseguire il lavoro. 'Queue.add' è ridondante. È sufficiente collegare il gestore direttamente a ciascuna richiesta asincrona. –

0

Si potrebbe voler dare un'occhiata a Event messaging between JavaScript objects.

ho usato un'implementazione simile al post sul blog con un plugin jQuery chiamato ajaxMonitor.

Il modo in cui funziona non appena viene richiamato uno dei richiami dalla richiesta AJAX, aggiorna una tabella HTML. I callback sono asincroni.

La stessa natura di AJAX significa asincrono. Quindi, processando la tua CODA nella callback di successo della tua richiesta AJAX, credo che realizzerebbe ciò che stai cercando.