11

Sono sorpreso di non riuscire a trovare una risposta chiara a questo. Così, in jQuery, si può fare questo:Come jQuery ha funzioni asincrone?

$(someElements).fadeOut(1000); 
$(someElements).remove(); 

Il che, inizierà un'animazione fadeOut, ma prima che venga completata l'esecuzione nel secondo periodo 1, gli elementi vengono rimossi dal DOM. Ma come è possibile? Continuo a leggere il codice JavaScript è single threaded (vedi anche: Is JavaScript guaranteed to be single-threaded?). So che posso fare neanche:

$(someElements).fadeOut(1000).promise().done(function() { 
    $(someElements).remove(); 
}); 

o meglio ancora:

$(someElements).fadeOut(1000, function() { 
    $(this).remove(); 
}); 

Quello che non capisco è come funziona JavaScript in un "filo singolo" ma sono in grado di utilizzare questi jQuery funzioni che eseguono in modo asincrono e visibile la modifica del DOM in posti diversi allo stesso tempo. Come funziona? Questa domanda non è: "Come posso risolvere questo problema".

+2

Risposta breve: animazione CSS o timer. –

+0

Penso che jQuery usi le code per le animazioni, è da qualche parte nei documenti .. – gpasci

risposta

5

jQuery animazioni (e praticamente tutte le animazioni basate su javascript) utilizzano i timer per eseguire le loro animazioni. La chiamata a .fadeOut() avvia solo l'animazione e non completa fino a qualche istante dopo l'esecuzione di una serie di operazioni del timer.

Questo è tutto ancora single-threaded. .fadeOut() esegue il primo passaggio dell'animazione, imposta un timer per il passaggio successivo e quindi il resto del javascript (incluso lo .remove()) viene eseguito fino al completamento. Quando il thread di javascript termina e il tempo trascorre per il timer, il timer scatta e il passo successivo dell'animazione avviene. Alla fine, quando tutti i passaggi dell'animazione sono completati, jQuery chiama la funzione di completamento dell'animazione. Questo è un callback che ti consente di fare qualcosa quando l'animazione è terminata.

Ecco come risolvere questo problema:

$(someElements).fadeOut(1000, function() { 
    $(this).remove(); 
}); 

si utilizza la funzione di completamento animazione e rimuovere solo la voce quando l'animazione è fatto.

+0

Se si desidera l'esecuzione asincrona si potrebbe considerare un web worker o utilizzare il (attualmente) sperimentale River Trail OpenCL bridge se si sta facendo un'intensa elaborazione dei dati. – FlavorScape

+0

In realtà preferisco JSTween perché può gestire qualsiasi proprietà. – FlavorScape

+1

@FlavorScape - I lavoratori Web non possono interagire con il DOM in modo che non siano di grande aiuto per le animazioni. – jfriend00

1

C'è un gestore di setInterval in jQuery che esegue le trasformazioni su tutte le proprietà di animazione registrate. Se arrivate da AS3, pensare ad esso come un gestore di EnterFrame, o come un metodo di disegno in OpenGL

+0

Penso che nelle ultime versioni di jQuery, possa usare il gestore requestAnimationFrame (evento inviato dal browser) come la funzione di aggiornamento/draw – FlavorScape

+0

requestAnimationFrame ha stato dentro e fuori da jQuery. E 'stato per un po', poi è stato tirato fuori a causa di alcuni problemi. Al momento non lo vedo nella versione di 1.7 per cui è stata aperta la fonte. – jfriend00

+0

@ jfriend00 sei corretto http://stackoverflow.com/questions/7999680/why-doesnt-jquery-use-requestanimationframe – FlavorScape

0

Tu ca usa delay() di aspettare per un certo tempo o utilizzare un callback per l'animazione, cambiando la fadeOut con animate . jQuery usa setTimeout per animare e accodare.

0

Più o meno allo stesso modo in cui 20 anni fa i sistemi operativi eseguivano il multitasking. Non c'erano discussioni, c'erano solo una lista di cose che richiedevano attenzione e un controller che avrebbe dato attenzione alle cose in base alla lista.

Un singolo thread consente di ripetere continuamente l'elenco di servizi che richiedono assistenza. L'unica differenza qui è che alcune cose hanno un periodo di attesa associato. Sono nella lista, ma sono contrassegnati per servire solo dopo un certo periodo. Si tratta essenzialmente di un'implementazione di scheduler molto semplice. Il kernel su un computer fa la stessa cosa. La tua CPU può eseguire solo alcuni programmi contemporaneamente e, anche in questo caso, solo in qualche modo. Il kernel del sistema operativo deve decidere chi attira l'attenzione su un millisecondo di millisecondo (vedi i jiffies). Il "kernel" o runtime di Javascript fa la stessa cosa, ma essenzialmente come se fosse eseguito su una CPU con un solo core.

Questo non parla di cose come le code di interruzione e quali una CPU può far fronte, e non sono sicuro che Javascript abbia qualche analogico, ma a un livello semplice, penso che sia una rappresentazione equa.

0

La filettatura singola non ha nulla a che fare con la programmazione asincrona. http://social.msdn.microsoft.com/Forums/uk/csharplanguage/thread/3de8670c-49ca-400f-a1dc-ce3a3619357d

Se si dispone di un solo thread su cui è possibile eseguire le istruzioni, non sarà/sempre/eseguibile. Durante quei punti vuoti, questa è un'opportunità per più lavoro. La programmazione asincrona interrompe il lavoro in blocchi capaci di rientro e il thread salta dove serve. (Spiegazione concettuale)

In questo caso, la tua domanda potrebbe essere più appropriatamente: Perché non si tratta di una chiamata bloccante? Nel qual caso la risposta è abbastanza chiara che separa le animazioni dell'interfaccia utente dalle chiamate dati. L'intero ambiente JS non dovrebbe bloccarsi per 1 secondo mentre si prendono piccole porzioni per animare un elemento che potrebbe essere il recupero o la trasformazione dei dati, l'accodamento dell'animazione per altri elementi, ecc.

Problemi correlati