2012-09-08 5 views
7

o ecmascript, pero me pregunto si la forma en que realmente sucede depende más de la implementación exacta.¿Cómo ocurre el corte de tiempo en javascript?

javascript es técnicamente de un solo hilo.

pero si hago algo así como

$myDIv.animate({ 
    height:"100px" 
}); 

no se hace ninguna diferencia si lo hago

A.

$myDIv.animate({ 
    height:"100px" 
}, null, my_cpu_heavy_function); 

o B.

$myDIv.animate({ 
    height:"100px" 
}); 
my_cpu_heavy_function(); 

porque en el segundo, la animación Lucharé por el tiempo de procesamiento con la función de CPU pesada y el aspecto de la animación sufriría, ¿verdad?

Entonces, ¿deja JavaScript de ejecutar al final de un bloque de código síncrono o corta un bloque en cualquier punto aleatorio para permitir que otro bloque se ejecute de forma asíncrona?

Respuesta

4

¿Hay alguna diferencia si hago A o B

sí, va a hacer una diferencia.

La segunda versión no lucha tanto por el tiempo de procesamiento. Es más como si el my_cpu_heavy_function ocupara todo el tiempo de procesamiento una vez que comienza, suponiendo que es sincrónico.

En otras palabras, una vez que comienza un poco de código síncrono, no termina hasta que se complete, independientemente de cualquier código asíncrono programado que pueda programarse para ejecutarse. El código asíncrono siempre se verá obligado a esperar a que se complete el código síncrono.

Entonces, lo que sucederá será que la animación comenzará y realizará su inicialización, pero luego el my_cpu_heavy_function se iniciará inmediatamente y bloqueará el resto de la animación hasta que se complete.

+0

cosas asíncrono todavía puede suceder (por ejemplo, descargar recursos remotos) s), aunque este no es el caso con 'animate', es solo que los * eventos/devoluciones de llamada * se retrasarán hasta que no haya otro código ejecutándose en la página. –

+0

@pst: la devolución de llamada es simplemente otra parte del código asíncrono que se ejecuta después del código animado asíncrono final. Todo el código asíncrono está bloqueado siempre que se esté ejecutando algún código síncrono. El código de sincronización no permitirá que ocurra ninguna sincronización hasta que se complete. –

+0

Con respecto a su comentario actualizado, sí (descarga de recursos remotos) pero eso está fuera del tiempo de ejecución de JavaScript. –

5

No hay división de tiempo en javascript. Javascript es de un solo hilo (excepto para los trabajadores de la web que no estamos discutiendo aquí). Un hilo de ejecución javascript se ejecuta hasta que se complete.

En el primer ejemplo de código, la animación hace su trabajo y cuando está completamente hecha, llama a su my_cpu_heavy_function.

En el segundo ejemplo de código, la animación se inicializa y configura un temporizador para su primer paso de animación. Luego vuelve y pasa a la siguiente línea de código. La animación solo ha comenzado (y configuró un temporizador por un corto tiempo en el futuro para hacer más trabajo) - no se ha completado. Luego, ejecuta su my_cpu_heavy_function y encierra toda la ejecución de javascript hasta que finaliza. La animación no se ejecuta en absoluto mientras se está ejecutando my_cpu_heavy_function. Cuando finaliza, el evento de temporizador que activará la animación se activará y la animación se ejecutará.

Las animaciones pueden "verse" como rebanadas de tiempo, pero en realidad no lo son. Las animaciones de jQuery avanzan un paso en la animación y luego configuran un temporizador por un poco de tiempo en el futuro y vuelven al sistema. Cuando el evento del temporizador se activa, jQuery realiza el siguiente paso en la animación y así sucesivamente.Cuando se dispara un evento de temporizador, coloca un evento de temporizador en la cola de eventos de JavaScript. Si no se está ejecutando javascript, la devolución de llamada del temporizador se inicia inmediatamente. Si javascript se está ejecutando actualmente, entonces el evento del temporizador se ubicará en la cola del evento hasta que termine el hilo de JavaScript actual. Cuando ese hilo termina, javascript busca en la cola de eventos para ver si hay algún evento esperando. Si hay, entonces llama a la devolución de llamada del evento.

Como tal, realmente no hay tiempo de corte para diferentes piezas de javascript. A dos piezas de código que desean ejecutar no se les asignan algunos ciclos de CPU, como ocurriría con los hilos reales en el código nativo. En JavaScript, una parte del código se ejecuta hasta que se completa y luego se puede iniciar el próximo evento. En cosas como las animaciones basadas en javascript, el corte temporal puede simularse de alguna manera haciendo una pequeña cantidad de trabajo y luego configurando un temporizador para un tiempo futuro y regresando al sistema. Tan pronto como termine de ejecutar, se puede ejecutar alguna otra aplicación de javascript, pero también se ejecutará hasta que finalice. Si todas las piezas de javascript solo hacen pequeñas cantidades de trabajo y luego configuran un temporizador para su siguiente trabajo, entonces todos pueden cooperar y parecerá que hay un corte de tiempo, pero solo funciona debido a la cooperación entre todos. Si una función como my_cpu_heavy_function viene y encierra la CPU por un tiempo, nadie más se ejecuta durante ese tiempo. La animación se detendría mientras se estaba ejecutando my_cpu_heavy_function.

Algunas operaciones en un navegador se llevan a cabo por código nativo en el navegador (como llamadas ajax, carga de imágenes, etc.). Estas tareas asíncronas pueden continuar en segundo plano mientras se ejecuta javascript, pero no notificarán javascript hasta que el hilo actual de la ejecución de javascript finalice y se pueda iniciar uno nuevo con la devolución de llamada de notificación.

Como ejemplo, supongamos que tenemos una imagen que tarda 1 segundo en cargar y una función intensiva de CPU que tarda 5 segundos en ejecutarse. entonces tenemos este código:

var img = new Image(); 
img.onload = function() { 
    alert("image is loaded now"); 
} 
img.src = "xxx.jpg"; 
longFunctionThatTakesFiveSecondsToRun(); 

Cuando ejecutamos este código, a pesar de que la imagen sólo toma 1 segundo para cargar internamente en el navegador, el manejador onload no se llamará hasta longFunctionThatTakesFiveSecondsToRun() se hace correr 5 segundos más tarde . Tiene que esperar hasta que se finalice el proceso actual de ejecución antes de que se pueda procesar el evento de carga.

Si desea saber más acerca de JavaScript colas de eventos y operaciones asincrónicas, ver estas respuestas relacionadas:

How does JavaScript handle AJAX responses in the background?

Race conditions with JavaScript event handling?

Can JS event handlers interrupt execution of another handler?

Do I need to be concerned with race conditions with asynchronous Javascript?

+0

hola, estaba cerrando algunas pestañas y revisé esta pregunta en busca de actualizaciones y me sentí mal porque me dio una respuesta tan detallada y nadie contestó en absoluto. Mucho de lo que dijiste lo sé, aunque principalmente programo en javascript. Sé que javascript no toca el procesador directamente y sé cómo rodeo threads y sobre el CLR (im. NET). es como si pasaras mucho tiempo diciendo algo porque no parecías respetar el conocimiento de alguien que hace una pregunta sobre el viejo y tonto javascript. obviamente sabes todo esto muy bien y quieres ayudar a los nuevos programadores. Así que gracias. –

Cuestiones relacionadas