¿Es una decisión de diseño deliberada o un problema con nuestros navegadores actuales que se rectificará en las próximas versiones?
¿Es una decisión de diseño deliberada o un problema con nuestros navegadores actuales que se rectificará en las próximas versiones?
Respuestas:
JavaScript no admite subprocesos múltiples porque el intérprete de JavaScript en el navegador es un subproceso único (AFAIK). Incluso Google Chrome no permitirá que el JavaScript de una sola página web se ejecute simultáneamente, ya que esto causaría problemas masivos de concurrencia en las páginas web existentes. Todo lo que Chrome hace es separar múltiples componentes (diferentes pestañas, complementos, etc.) en procesos separados, pero no puedo imaginar una sola página que tenga más de un hilo de JavaScript.
Sin embargo, puede usar, como se sugirió, setTimeout
para permitir algún tipo de programación y concurrencia "falsa". Esto hace que el navegador recupere el control del hilo de renderizado e inicie el código JavaScript proporcionado asetTimeout
después del número de milisegundos dado. Esto es muy útil si desea permitir que la ventana gráfica (lo que ve) se actualice mientras realiza operaciones en ella. Simplemente recorrer, por ejemplo, las coordenadas y actualizar un elemento en consecuencia, solo le permitirá ver las posiciones de inicio y finalización, y nada en el medio.
Utilizamos una biblioteca de abstracción en JavaScript que nos permite crear procesos y subprocesos que son administrados por el mismo intérprete de JavaScript. Esto nos permite ejecutar acciones de la siguiente manera:
Esto permite alguna forma de programación y simula paralelismo, inicio y detención de subprocesos, etc., pero no será verdadero subprocesamiento múltiple. No creo que alguna vez se implemente en el lenguaje en sí, ya que el verdadero subproceso múltiple solo es útil si el navegador puede ejecutar una sola página con subprocesos múltiples (o incluso más de un núcleo), y las dificultades son mucho mayores. que las posibilidades extra.
Para el futuro de JavaScript, mira esto: https://developer.mozilla.org/presentations/xtech2006/javascript/
El subprocesamiento múltiple de JavaScript (con algunas limitaciones) está aquí. Google implementó trabajadores para Gears, y los trabajadores se están incluyendo con HTML5. La mayoría de los navegadores ya han agregado soporte para esta función.
La seguridad de los subprocesos de los datos está garantizada porque todos los datos comunicados al / del trabajador se serializan / copian.
Para más información, lea:
Tradicionalmente, JS estaba destinado a piezas de código cortas y de ejecución rápida. Si tenía cálculos importantes, lo hizo en un servidor: la idea de una aplicación JS + HTML que se ejecutara en su navegador durante largos períodos de tiempo haciendo cosas no triviales era absurda.
Por supuesto, ahora tenemos eso. Sin embargo, los navegadores tardarán un poco en ponerse al día: la mayoría de ellos se han diseñado en torno a un modelo de un solo subproceso, y cambiar eso no es fácil. Google Gears evita muchos problemas potenciales al requerir que la ejecución en segundo plano esté aislada: sin cambiar el DOM (ya que no es seguro para subprocesos), sin acceder a los objetos creados por el subproceso principal (ídem). Si bien es restrictivo, este será probablemente el diseño más práctico para el futuro cercano, tanto porque simplifica el diseño del navegador como porque reduce el riesgo involucrado en permitir que los codificadores JS sin experiencia jueguen con hilos ...
@marcio :
¿Por qué es esa una razón para no implementar multi-threading en Javascript? Los programadores pueden hacer lo que quieran con las herramientas que tienen.
Entonces, no les demos herramientas que sean tan fáciles de usar que cualquier otro sitio web que abra termine con mi navegador. Una implementación ingenua de esto lo llevaría directamente al territorio que causó tantos dolores de cabeza a MS durante el desarrollo de IE7: los autores de complementos jugaron rápido y suelto con el modelo de subprocesos, lo que resultó en errores ocultos que se hicieron evidentes cuando los ciclos de vida de los objetos cambiaron en el hilo primario . MALO. Si está escribiendo complementos ActiveX multiproceso para IE, supongo que viene con el territorio; no significa que deba ir más allá de eso.
No sé la razón de esta decisión, pero sé que puede simular algunos de los beneficios de la programación multiproceso utilizando setTimeout. Puede dar la ilusión de múltiples procesos haciendo cosas al mismo tiempo, aunque en realidad, todo sucede en un hilo.
Simplemente haga que su función haga un poco de trabajo y luego llame a algo como:
setTimeout(function () {
... do the rest of the work...
}, 0);
Y cualquier otra cosa que necesite hacer (como actualizaciones de UI, imágenes animadas, etc.) sucederá cuando tengan la oportunidad.
loop
dentro, setTimeout
pero aparentemente eso no funciona. ¿Has hecho algo así o tienes un truco? un ejemplo sería para una matriz de 1000 elementos, espero usar dos para bucles dentro de dos setTimeout
llamadas, de modo que el primer bucle y el elemento de impresión 0..499
, el segundo bucle y el elemento de impresión 500..999
.
¿Quiere decir por qué el lenguaje no admite subprocesos múltiples o por qué los motores JavaScript en los navegadores no admiten subprocesos múltiples?
La respuesta a la primera pregunta es que JavaScript en el navegador debe ejecutarse en un entorno limitado y de forma independiente de la máquina / SO, agregar soporte de subprocesamiento múltiple complicaría el idioma y lo vincularía demasiado al SO.
Node.js 10.5+ admite subprocesos de trabajo como característica experimental (puede usarlo con - bandera de trabajador experimental habilitada): https://nodejs.org/api/worker_threads.html
Entonces, la regla es:
Los hilos de trabajo están destinados a ser hilos de larga duración, lo que significa que genera un hilo de fondo y luego se comunica con él a través de la transmisión de mensajes.
De lo contrario, si necesita ejecutar una gran carga de CPU con una función anónima, puede ir a https://github.com/wilk/microjob , una pequeña biblioteca construida alrededor de hilos de trabajo.
Tal como dijo Matt B, la pregunta no es muy clara. Suponiendo que está preguntando sobre el soporte de subprocesos múltiples en el idioma: porque no es necesario para el 99.999% de las aplicaciones que se ejecutan actualmente en el navegador. Si realmente lo necesita, existen soluciones alternativas (como usar window.setTimeout).
En general, el subprocesamiento múltiple es muy, muy, muy, muy, muy, muy difícil (¿dije que es difícil?) Acertar, a menos que establezca restricciones adicionales (como usar solo datos inmutables).
Intel ha estado haciendo una investigación de código abierto sobre subprocesos múltiples en Javascript, se mostró recientemente en GDC 2012. Aquí está el enlace para el video . El grupo de investigación utilizó OpenCL, que se centra principalmente en conjuntos de chips Intel y el sistema operativo Windows. El proyecto tiene el nombre en código RiverTrail y el código está disponible en GitHub
Algunos enlaces más útiles:
Construyendo una autopista informática para aplicaciones web
Actualmente, algunos navegadores admiten subprocesos múltiples. Entonces, si lo necesita, puede usar bibliotecas específicas. Por ejemplo, vea los siguientes materiales:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (admite hilos de fondo);
https://keithwhor.github.io/multithread.js/ (la biblioteca).
Son las implementaciones las que no admiten subprocesos múltiples. Actualmente, Google Gears proporciona una forma de utilizar algún tipo de concurrencia mediante la ejecución de procesos externos, pero eso es todo.
Se supone que el nuevo navegador que Google lanzará hoy (Google Chrome) ejecuta un código en paralelo separándolo en el proceso.
El lenguaje central, por supuesto, puede tener el mismo soporte que, por ejemplo, Java, pero el soporte para algo como la concurrencia de Erlang no está cerca del horizonte.
Javascript es un lenguaje de subproceso único. Esto significa que tiene una pila de llamadas y un montón de memoria. Como se esperaba, ejecuta el código en orden y debe terminar de ejecutar un código de pieza antes de pasar al siguiente. Es sincrónico, pero a veces eso puede ser dañino. Por ejemplo, si una función tarda un tiempo en ejecutarse o tiene que esperar algo, se congela todo mientras tanto.
Sin el soporte de idioma adecuado para la sincronización de subprocesos, ni siquiera tiene sentido que las nuevas implementaciones lo intenten. Las aplicaciones JS complejas existentes (por ejemplo, cualquier cosa que use ExtJS) probablemente se bloquee inesperadamente, pero sin una synchronized
palabra clave o algo similar, también sería muy difícil o incluso imposible escribir nuevos programas que se comporten correctamente.
Sin embargo, puede usar la función eval para llevar la concurrencia EN ALGUNA EXTENSIÓN
/* content of the threads to be run */
var threads = [
[
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');"
],
[
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');"
]
];
window.onload = function() {
var lines = 0, quantum = 3, max = 0;
/* get the longer thread length */
for(var i=0; i<threads.length; i++) {
if(max < threads[i].length) {
max = threads[i].length;
}
}
/* execute them */
while(lines < max) {
for(var i=0; i<threads.length; i++) {
for(var j = lines; j < threads[i].length && j < (lines + quantum); j++) {
eval(threads[i][j]);
}
}
lines += quantum;
}
}
El subprocesamiento múltiple con javascript es claramente posible utilizando los trabajadores web traídos por HTML5.
La principal diferencia entre los trabajadores web y un entorno estándar de subprocesos múltiples es que los recursos de memoria no se comparten con el subproceso principal, una referencia a un objeto no es visible de un subproceso a otro. Los hilos se comunican intercambiando mensajes, por lo tanto, es posible implementar un algoritmo de sincronización y llamada de método concurrente siguiendo un patrón de diseño controlado por eventos.
Existen muchos marcos que permiten estructurar la programación entre subprocesos, entre ellos OODK-JS, un marco OOP js que admite programación concurrente https://github.com/GOMServices/oodk-js-oop-for-js