2010-07-23 19 views
6

Comprendo che Javascript non ha più thread, ma mi piacerebbe sapere se il codice seguente ha qualche possibilità di rottura. La mia comprensione è che, a meno che non venga chiamata una funzione asincrona, come setTimeout o una chiamata AJAX, che una volta che un blocco di codice inizia l'esecuzione non c'è modo di sospenderlo fino a quando non completa o chiama una funzione asincrona.Esiste la possibilità che due istanze di funzioni JavaScript asincrone eseguano contemporaneamente due blocchi di codice?

In pratica, gli utenti selezionano più caselle di controllo e poi toccano un pulsante che esegue l'elaborazione AJAX delle loro selezioni. Il mio obiettivo è avere un'icona "Salvataggio in corso ..." che permanga solo fino a quando tutti i processi AJAX sono completi e, dopo tutto, viene visualizzato un messaggio di successo.

salvo eventuali errori AJAX, a condizione che la funzione di richiamata nel jQuery.post eseguito nella sua interezza, senza interruzione, non vedo come il if(numProcessed == toProcess) avrebbe mai eseguire più di una volta o meno di una volta. Ma se due callback AJAX entrano nella funzione di callback, entrambi incrementano il contatore numProcessed prima di ottenere il seguente numero if, quindi sembra che il codice interno venga eseguito due volte.

var numProcessed = 0; 
var checkedBoxes = jQuery("input[type=checkbox]:checked"); 
var toProcess = checkedBoxes.size(); 

checkedBoxes.each(function() { 
    jQuery.post('somepage.php',{...},function(results) { 
    numProcessed++; 
    if(numProcessed == toProcess) { 
     jQuery("#saving-message").remove(); 
     jQuery("#feedback-panel").text('Successfully processed all selections.'); 
    } 
    } 
} 
+0

Non conosco l'esecuzione di javascript o browser abbastanza bene da sapere come implementarlo, ma se hai il controllo completo dell'implementazione di entrambi i pezzi di codice che eseguono l'elaborazione lungo/pesante, è possibile creare due oggetti che hanno una funzione "processo successivo", mantenendo un conteggio interno all'interno dell'oggetto e in qualche modo per segnalare che l'elaborazione è completa (un'altra funzione o un "booleano" completato). Chiama ciascuno di essi fino a quando entrambi hanno terminato l'elaborazione. –

+0

@Merlyn: avevo preso in considerazione l'idea di concatenare, quindi dopo averlo completato inizia quello successivo. Le mie preoccupazioni erano che 1) non sarebbe così veloce dato che tra ognuna dobbiamo aspettare che la richiesta HTML arrivi al server piuttosto che tutte le code immediatamente. 2) Se qualcosa non funziona su un link della catena, tutti i rimanenti non verranno elaborati. 3) A seconda del numero di articoli, questo potrebbe sovraccaricare lo stack poiché creerebbe chiusure annidate per ciascun articolo. Potrei sbagliarmi, ma sono contento di poter fare affidamento sulla single-threaded di Javascript invece di creare una struttura più complessa. –

+0

@Merlyn: rileggendo il tuo commento, sembra che tu abbia organizzato una struttura migliore di quella che avevo in mente. Il tuo consentirebbe il # 2 e il # 3 del mio commento di essere risolto in modo abbastanza banale, ma il # 1 potrebbe ancora essere un problema. –

risposta

2

C'è solo un filo in JavaScript in modo che ogni funzione che vuole essere l'esecuzione viene messa in pila e devono aspettare fino a quando tutti gli altri sono eseguiti. Nel tuo caso "ciascuno" è la prima funzione nello stack, quindi ogni funzione di callback deve attendere e verrà eseguita nell'ordine in cui sono messi in pila. Dopo tutto "numProcessed == toProcess" potrebbe essere una sola volta true.

+0

Molto bene, felice di sentirlo. Penso che ciò che confonde la natura single-threaded di Javascript sia che ha queste funzioni asincrone che in un senso più ampio mi fa pensare a Javascript come una sorta di multi-thread, in quanto ha un processo in background che piomba dentro e lancia le esecuzioni callback in coda, piuttosto che tutto è assolutamente procedurale/sincrono. –

Problemi correlati