2010-07-20 9 views
8

È possibile fare le cose in modo asincrono in javascript (AJAX a parte)? Ad esempio, per iterare più array allo stesso tempo. Com'è fatto? Un breve esempio sarebbe carino. La ricerca di questo è stato difficile, a causa di tutto l'inquinamento ajax, che non è quello che sto cercando.Programmazione asincrona in javascript (NON AJAX)

Grazie in anticipo.

+1

Sembra che ti interessi l'elaborazione parallela, non necessariamente l'esecuzione asincrona? Non l'ho approfondito, ma gli iframe non usano un thread js separato? Non riesco a immaginare che sarebbe divertente, ma potresti essere in grado di svolgere alcune attività parallele utilizzando le funzioni negli iframe. – jball

+0

Gli iframe potrebbero essere una tecnica interessante, anche se penso che il sovraccarico dell'iframe sarebbe più negativo di quello che darebbe la programmazione asincrona. – aepheus

+0

Idea interessante, ma penso che nella maggior parte o in tutti i browser, un iframe utilizza lo stesso thread JS. In realtà penso in tutto tranne Chrome, tutte le finestre e le schede utilizzano lo stesso thread JS. – Grumdrig

risposta

9

Usa web Workers. Ma ricorda che è una funzionalità molto nuova e non tutti i browser sono pienamente supportati.

+0

Esistono funzionalità asincrone prima di html 5? – aepheus

+1

@aepheus: Non proprio: JS è stato creato come thread singolo, quindi mentre è possibile utilizzare setTimeout() come si vede nella risposta di Grumdrig, l'esecuzione del programma viene eseguita solo in un thread. – Piskvor

2

Un nuovo sviluppo in questo campo è HTML5 Web Workers.

+3

Ottimo, ora c'è un nuovo modo molto complesso per chiedermi perché i miei processori raggiungono il picco quando si visita un sito! : P – Abel

+1

@Abel stavo pensando la stessa cosa. Ora una pagina web può pegging tutti i 4 cpus invece di uno solo. –

+0

Yay, ora possiamo masterizzare tutte e 4 le CPU con cicli "for" vuoti! Preparati per alcuni laptop HOT! –

6

È possibile utilizzare setTimeout.

setTimeout(function() { iterateArray(array1); reportDone(1); }, 0); 
setTimeout(function() { iterateArray(array2); reportDone(2); }, 0); 

Non sono sicuro di quanto sarà simultaneo, ma si tratta di un modello di programmazione asincrono.

+0

+1 Buona idea, a volte le vecchie e buone cose semplici fanno semplicemente :) – Abel

+0

Suppongo che questo darebbe comunque esecuzione sincrona (anche se come si afferma sarebbe in un modello asincrono). L'array 1 verrà sempre completato, quindi verrà avviato l'array 2, ecc. Non vedo molte ragioni per questo oltre a rendere il codice confuso. – aepheus

+0

Sì, sono abbastanza d'accordo. – Grumdrig

1

JavaScript è normalmente single threaded; non puoi fare più cose contemporaneamente. Se il tuo codice JavaScript è troppo lento, dovrai scaricare il lavoro. Il nuovo modo è utilizzare web workers, come altri hanno notato. La vecchia maniera è spesso quella di usare AJAX e fare il lavoro sul server. (O con i lavoratori web o con AJAX, gli array dovrebbero essere serializzato e il risultato deserializzati)

4

Come affermato da Grumdrig è possibile scrivere codice come questo:

setTimeout(function() { iterateArray(array1); reportDone(1); }, 0); 
setTimeout(function() { iterateArray(array2); reportDone(2); }, 0); 

ma sarà ancora non eseguiti contemporaneamente . Ecco un'idea generale di ciò che accade dopo tali timeout si chiamano:

  • Qualsiasi codice dopo le setTimeout chiamate verrà eseguito immediatamente, tra cui torna a chiamare funzioni.
  • Se ci sono altri timer in coda che sono in corrispondenza del loro ritardo o intervallo, verranno eseguiti uno alla volta.
  • Mentre un timer è in esecuzione, un altro potrebbe raggiungere il suo intervallo/tempo di ritardo, ma non verrà eseguito fino a quando non è terminato l'ultimo.
  • Alcuni browser danno priorità agli eventi attivati ​​dall'interazione dell'utente, ad esempio onclick e onmousemove, nel qual caso le funzioni associate a tali eventi verranno eseguite a spese della precisione del timer.
  • Continuerà fino all'apertura (nessun timer o gestore di eventi in precedenza richiesto per l'esecuzione). Solo allora verranno eseguite le funzioni nel codice di esempio. Di nuovo uno alla volta, con il primo probabile, ma non certo l'esecuzione prima. Inoltre, mi sto azzardando a supporre che alcuni browser potrebbero imporre un tempo di ritardo minimo, il che farebbe girare qualsiasi timer impostato con un ritardo di 0 millisecondi anche più tardi del previsto.

Ovviamente non vi è alcun vantaggio in termini di prestazioni per l'esecuzione di codice come questo. In ogni caso ci vorrà più tempo per completare le cose. Tuttavia, nei casi in cui un singolo task impiega così tanto tempo a bloccare il browser (e probabilmente invia "Script richiede troppo tempo" per gli avvisi del browser), può essere utile suddividerlo in pezzi di esecuzione più piccoli più veloci che vengono eseguiti sequenzialmente dopo un certo intervallo di tempo. , dando così al browser un po 'di tempo per respirare.

I Web worker sono stati citati e, se non si è interessati alla compatibilità di IE, è possibile utilizzarli per una concorrenza reale. Tuttavia ci sono alcune severe limitazioni sul loro uso imposte per ragioni di sicurezza.Per uno non possono interagire con il DOM in alcun modo, il che significa che le eventuali modifiche alla pagina devono ancora essere eseguite in modo sincrono. Inoltre, tutti i dati trasmessi da e verso i lavoratori sono serializzati in transito, il che significa che non è possibile utilizzare oggetti JavaScript reali. Detto questo, per l'elaborazione intensiva dei dati, i Web Worker sono probabilmente una soluzione migliore rispetto alla rottura di una funzione in più attività ritardate del timer.

+0

Sarebbe utile fare var tId1 = setTimeout (function() {iterateArray (array1); reportDone (1);}, 0); var tId2 = setTimeout (function() {iterateArray (array2); reportDone (2);}, 0); – mplungjan

+0

L'unica differenza che vedo è l'assegnazione degli ID timer alle variabili. Tutti gli ID del timer sono davvero buoni per l'annullamento di detti timer. Un po 'inutile per un timeout di 0 ms una volta sola. – MooGoo

1

Devo essere d'accordo con MooGoo, mi chiedo anche perché si possa correre attraverso un array così grande in una volta.

C'è un'estensione in JavaScript denominata StratifiedJS, che consente di fare più cose contemporaneamente purché siano asincrone. Inoltre, i webworker sono una "soluzione" imbarazzante che rende le cose più complicate, inoltre, non funzionano in IE.

In StratifiedJS è possibile scrivere.

waitfor { 
    // do something long lasting here... 
} 
and { 
    // do something else at the same time... 
} 
// and when you get here, both are done 
Problemi correlati