2011-11-01 24 views
5

Siempre escucho que el JavaScript tiene un solo hilo; que cuando se ejecuta JavaScript, todo se ejecuta en el mismo mosh pit global, todo en un solo hilo.JavaScript y un solo hilo

Si bien eso puede ser cierto, ese subproceso de ejecución única puede engendrar nuevos subprocesos, asíncronos que reqieren datos al hilo principal, ¿correcto? Por ejemplo, cuando se envía un XMLHttpRequest, ¿no crea el navegador un nuevo hilo que realiza la transacción HTTP y vuelve a invocar las devoluciones de llamada en el hilo principal cuando se devuelve XMLHttpRequest?

¿Qué hay de los temporizadores - setTimeout y setInterval? ¿Cómo funcionan?

¿Este hilo único es el resultado del lenguaje? ¿Qué ha impedido que JavaScript tenga una ejecución de subprocesos múltiples antes del nuevo borrador de Web Workers?

+0

intérpretes javaScript a menudo comparte navegadores hilo de interfaz de usuario – david

+2

la próxima vez que estoy hablando de alcance global, voy a utilizar el término ** global mosh pit ** :) –

+0

inb4 HTML5 web workers – Ben

Respuesta

3

Consulte this post para obtener una descripción de cómo funciona la cola de eventos de JavaScript, incluido cómo se relaciona con las llamadas ajax.

El navegador utiliza al menos un proceso/subproceso del sistema operativo nativo para manejar la interfaz real del sistema operativo para recuperar eventos del sistema (mouse, teclado, temporizadores, eventos de red, etc.). Si hay más de un subproceso de nivel de sistema operativo nativo depende de la implementación del navegador y no es realmente relevante para el comportamiento de Javascript. Todos los eventos del mundo exterior pasan por la cola de eventos de JavaScript y no se procesa ningún evento hasta que se completa un hilo de ejecución de JavaScript anterior y luego se saca el siguiente evento de la cola asignada al motor de JavaScript.

4

Su JavaScript en sí es de subproceso único. Sin embargo, puede interactuar con otros hilos en el navegador (que a menudo se escribe con algo como C y C++). Así es como funciona el XHR asíncrono. El navegador puede crear un nuevo hilo (o puede volver a usar una ya existente con un bucle de eventos.)

temporizadores y los intervalos tratará de hacer que su JavaScript ejecutar más tarde, pero si usted tiene un while(1){ ; } ejecución no esperan un temporizador o intervalo para interrumpirlo.

(corregir: dejado algo.) El roscado simple es en gran medida un resultado de la especificación ECMA. Realmente no hay construcciones de lenguaje para tratar con múltiples hilos. No sería imposible escribir un intérprete de JavaScript con múltiples hilos y las herramientas para interactuar con ellos, pero nadie realmente lo hace. Ciertamente, nadie lo hará en un navegador web; se ensuciaría todo arriba. (Si está haciendo algo del lado del servidor como Node.js, verá que han evitado el subprocesamiento múltiple en JavaScript adecuado a favor de un bucle de eventos elegante y multiprocesamiento opcional.)

6

XMLHttpRequest, notablemente , no bloquea el hilo actual. Sin embargo, sus detalles dentro del tiempo de ejecución no se describen en ninguna especificación. Puede ejecutarse en un subproceso separado o dentro del subproceso actual, haciendo uso de E/S sin bloqueo.

setTimeout y setInterval establecen temporizadores que, cuando se ejecutan a cero, agregan un elemento para la ejecución, ya sea una línea de código de una función/devolución de llamada, a la pila de ejecución, iniciando el motor JavaScript si se detuvo la ejecución del código. En otras palabras, le dicen al motor de JavaScript que haga algo después de que haya terminado de hacer lo que está haciendo actualmente. Para ver esto en acción, configure múltiples setTimeout (s) dentro de un método y llámelo.

0

El navegador puede tener otros hilos para hacer el trabajo, pero su código Javascript se ejecutará en un hilo. Así es como funcionaría en la práctica.

En caso de tiempo de espera, el navegador creará un hilo separado para esperar a que expire el tiempo de espera o usar algún otro mecanismo para implementar la lógica de tiempo real. Luego expira el tiempo de espera, el mensaje se colocará en la cola del evento principal que le dice al tiempo de ejecución que ejecute su controlador. y eso sucederá tan pronto como el mensaje sea recogido por el hilo principal.

La solicitud de AJAX funcionaría de manera similar. Algún hilo interno del navegador puede conectarse al servidor y esperar la respuesta, y una vez que la respuesta esté disponible coloque el mensaje apropiado en la cola del evento principal para que el hilo principal ejecute el controlador.

En todos los casos, su código se ejecutará por el hilo principal. Esto no es diferente de la mayoría de otros sistemas de interfaz de usuario, excepto que el navegador oculta esa lógica. En otras plataformas, es posible que tenga que tratar con hilos separados y garantizar la ejecución de los controladores en el hilo de la interfaz de usuario.

0

Poniéndolo de manera más simple que hablando en términos de subprocesos, en general (para los navegadores que conozco) solo habrá un bloque de ejecución de JavaScript en un momento dado.

Cuando se hace una petición Ajax asíncrono o llame setTimeout o setInterval el navegador puede gestionar ellos en otro hilo, pero el código JS real en las devoluciones de llamada no se ejecutará hasta algún momento después del bloque que se está ejecutando de código termina. Simplemente se pone en cola.

Una simple prueba para demostrar esto es si se pone un trozo de código en ejecución relativamente largo después de un setTimeout pero en el mismo bloque:

setTimeout("alert('Timeout!');", 5); 
alert("After setTimeout; before loop");  
for (var i=0, x=0; i < 2000000; i++) { x += i }; 
alert("After loop"); 

Si ejecuta lo anterior verá el "Después de setTimeout "alerta, luego habrá una pausa mientras el bucle se ejecuta, luego verás" Después del bucle ", y solo después de eso verás" ¡Tiempo de espera! " - aunque claramente ha pasado mucho más tiempo que 5ms (especialmente si tarda un poco en cerrar la primera alerta).

Una razón citada con frecuencia para el hilo único es que simplifica el trabajo del navegador al renderizar la página, porque no se obtiene la situación de muchos hilos de JavaScript diferentes tratando de actualizar el DOM al mismo tiempo hora.

0

Javascript es un lenguaje diseñado para ser incrustado. Se puede y se ha utilizado en programas que ejecutan javascript simultáneamente en diferentes hilos operativos. No hay mucha demanda de un lenguaje incrustado para controlar explícitamente la creación de nuevos subprocesos de ejecución, pero ciertamente se puede hacer proporcionando un objeto host con las capacidades requeridas. El WHATWG realmente includes a justification for their decision not to push a standard concurrent execution capability for browsers.

Cuestiones relacionadas