threads thread new javascript multithreading

thread - Ejecutar tarea de fondo en Javascript



javascript new thread (9)

Tengo una tarea intensiva de cpu que necesito ejecutar en el cliente. Idealmente, me gustaría poder invocar la función y desencadenar eventos de progreso mediante jquery para poder actualizar la interfaz de usuario.

Sé que javascript no admite subprocesos, pero he visto algunos artículos prometedores que intentan imitar los subprocesos usando setTimeout.

¿Cuál es el mejor enfoque a utilizar para esto? Gracias.


Aquí está mi solución al problema, en caso de que alguien quiera un simple fragmento de código que pueda copiarse:

var iterate = function (from, to, action, complete) { var i = from; var impl = function () { action(i); i++; if (i < to) setTimeout(impl, 1); else complete(); }; impl(); };


Básicamente, lo que quieres hacer es dividir la operación en partes. Entonces, digamos que tiene 10 000 elementos que desea procesar, almacénelos en una lista y luego procese una pequeña cantidad de ellos con un pequeño retraso entre cada llamada. Aquí hay una estructura simple que podrías usar:

function performTask(items, numToProcess, processItem) { var pos = 0; // This is run once for every numToProcess items. function iteration() { // Calculate last position. var j = Math.min(pos + numToProcess, items.length); // Start at current position and loop to last position. for (var i = pos; i < j; i++) { processItem(items, i); } // Increment current position. pos += numToProcess; // Only continue if there are more items to process. if (pos < items.length) setTimeout(iteration, 10); // Wait 10 ms to let the UI update. } iteration(); } performTask( // A set of items. [''a'', ''b'', ''c'', ''d'', ''e'', ''f'', ''g'', ''h'', ''i'', ''j'', ''k'', ''l'', ''m'', ''n'', ''o''], // Process two items every iteration. 2, // Function that will do stuff to the items. Called once for every item. Gets // the array with items and the index of the current item (to prevent copying // values around which is unnecessary.) function (items, index) { // Do stuff with items[index] // This could also be inline in iteration for better performance. });

También tenga en cuenta que Google Gears tiene soporte para trabajar en un hilo separado . Firefox 3.5 también introdujo sus propios trabajadores que hacen lo mismo (aunque siguen el estándar W3 , mientras que Google Gears usa sus propios métodos).


Dependiendo de cuáles sean sus requisitos, puede salirse fácilmente usando Gears. Gears soporta hilos, que podrían hacer lo que quieras.

Como mencionaste, setTimeout es la otra opción. Dependiendo del tipo de tarea, puede transferir cada iteración de un bucle a una llamada setTimeout separada con algo de espacio entre ellas, o puede que necesite separar partes de su algoritmo principal en funciones separadas que pueden llamarse una por una en de la misma manera que llamarías a cada iteración.


Este es un ejemplo muy básico de cómo crear hilos en JavaScript. Tenga en cuenta que depende de usted interrumpir las funciones de su hilo (instrucción de pantalla). Si lo desea, puede usar un setTimeout en lugar de mi bucle while para ejecutar el programador periódicamente. Tenga en cuenta que este ejemplo solo funciona con la versión de JavaScript 1.7+ (firefox 3+). Puede probarlo aquí: http://jslibs.googlecode.com/svn/trunk/jseval.html

//// thread definition function Thread( name ) { for ( var i = 0; i < 5; i++ ) { Print(i+'' (''+name+'')''); yield; } } //// thread management var threads = []; // thread creation threads.push( new Thread(''foo'') ); threads.push( new Thread(''bar'') ); // scheduler while (threads.length) { var thread = threads.shift(); try { thread.next(); threads.push(thread); } catch(ex if ex instanceof StopIteration) { } }

La salida es:

0 (foo) 0 (bar) 1 (foo) 1 (bar) 2 (foo) 2 (bar) 3 (foo) 3 (bar) 4 (foo) 4 (bar)


Gran respuesta Kevin! Escribí algo similar hace unos años, aunque menos sofisticado. El código fuente está aquí si alguien lo quiere:

http://www.leapbeyond.com/ric/jsUtils/TaskQueue.js

Cualquier cosa con un método run() se puede poner en cola como una tarea. Las tareas pueden volver a hacer cola para realizar el trabajo en trozos. Puede priorizar tareas, agregarlas / eliminarlas a voluntad, pausar / reanudar toda la cola, etc. Funciona bien con operaciones asíncronas: mi uso original para esto fue para administrar varias solicitudes de petición simultáneas de XMLHttp.

El uso básico es bastante simple:

var taskQueue = new TaskQueue(); taskQueue.schedule("alert(''hello there'')");

Los comentarios del encabezado en el archivo .js proporcionan ejemplos más avanzados.


Mi recomendación más fuerte es mostrar un load.gif simple durante la operación. El usuario a menudo acepta cierta duración si se le ha "dicho" que podría llevar algún tiempo.

Ajaxload - Ajax loading gif generator


Parece que este problema se ha resuelto en el propio nodo.
requiere child_process que se incluye en nodejs 0.10.4


Si puede imponer el uso del navegador, o de lo contrario ya sabe que es una nueva versión de Firefox, puede usar los nuevos Trabajadores Web de Mozilla. Te permite generar nuevos hilos.


Tuve un problema similar que resolver recientemente, en el que necesitaba mantener mi hilo de UI libre mientras crujía algunos datos para mostrar.

Escribí una biblioteca Background.js para manejar algunos escenarios: una cola de fondo secuencial (basada en la biblioteca WorkerQueue), una lista de trabajos donde se llama cada uno en cada temporizador y un iterador de matrices para ayudar a dividir su trabajo en partes más pequeñas . Ejemplos y código aquí: https://github.com/kmalakoff/background

¡Disfrutar!