2010-07-20 10 views
8

¿Es posible hacer cosas de forma asincrónica en javascript (AJAX a un lado)? Por ejemplo, para iterar múltiples matrices al mismo tiempo. ¿Cómo se hace? Un breve ejemplo sería bueno. La búsqueda de esto fue difícil, debido a toda la contaminación de Ajax, que no es lo que estoy buscando.Programación asincrónica en javascript (NO AJAX)

Gracias de antemano.

+1

Parece que le interesa el procesamiento en paralelo, no necesariamente la ejecución asincrónica? No he investigado en profundidad, pero ¿los iframes usan un hilo js por separado? No me puedo imaginar que sería divertido, pero es posible que puedas hacer algunas tareas paralelas usando funciones en iframes. – jball

+0

iframes podría ser una técnica interesante, aunque creo que la sobrecarga del iframe sería más negativa que la que proporcionaría la programación asíncrona. – aepheus

+0

Una idea interesante, pero creo que en la mayoría de los navegadores, un iframe usa el mismo hilo JS. De hecho, creo que en todo menos en Chrome, todas las ventanas y pestañas usan el mismo hilo JS. – Grumdrig

Respuesta

9

Uso web Workers. Pero recuerda que es una característica muy nueva y no todos los navegadores son totalmente compatibles.

+0

¿Hay características asíncronas antes de html 5? – aepheus

+1

@aepheus: En realidad, JS no se creó como un único subproceso, por lo que si bien puede usar setTimeout() como se ve en la respuesta de Grumdrig, la ejecución del programa se ejecuta en un solo subproceso. – Piskvor

2

Un nuevo desarrollo en este campo es HTML5 Web Workers.

+3

¡Genial, ahora hay una nueva forma realmente enrevesada de hacerme preguntar por qué mis procesadores alcanzan su punto máximo cuando visitan un sitio! : P – Abel

+1

@Abel Estaba pensando lo mismo. Ahora, una página web puede vincular las 4 cpus en lugar de solo una. –

+0

¡Yay, ahora podemos grabar las 4 CPU con bucles "para" vacíos! ¡Prepárate para algunas laptops HOT! –

6

Puede usar setTimeout.

setTimeout(function() { iterateArray(array1); reportDone(1); }, 0); 
setTimeout(function() { iterateArray(array2); reportDone(2); }, 0); 

No estoy seguro de cuán concurrente será, pero es un modelo de programación asincrónico.

+0

+1 Buena idea, a veces las buenas y sencillas cosas simplemente lo hacen :) – Abel

+0

Supongo que esto todavía daría la ejecución sincrónica (aunque como usted declara sería en un modelo asincrónico). La matriz 1 siempre se completará, luego la matriz 2 comenzará, etc. No veo muchas razones para esto aparte de hacer que el código sea confuso. – aepheus

+0

Sí, estoy bastante de acuerdo. – Grumdrig

1

JavaScript es normalmente de una sola hebra; no puedes hacer varias cosas a la vez. Si su código JavaScript es demasiado lento, deberá descargar el trabajo. La nueva forma es usar web workers, como han notado otros. La vieja manera es a menudo usar AJAX y hacer el trabajo en el servidor. (Ya sea con los trabajadores web o con AJAX, las matrices tendrían que ser serializado y el resultado deserializado)

4

Según lo indicado por Grumdrig puede escribir código como este:

setTimeout(function() { iterateArray(array1); reportDone(1); }, 0); 
setTimeout(function() { iterateArray(array2); reportDone(2); }, 0); 

Sin embargo, todavía no se ejecutarán simultáneamente . He aquí una idea general de lo que sucede después de dichos tiempos de espera son llamados:

  • Cualquier código después de las llamadas setTimeout se ejecutará inmediatamente, incluyendo la vuelve a llamar a las funciones.
  • Si hay otros temporizadores en la cola que están en o después de su retraso o intervalo de tiempo, se ejecutarán uno a la vez.
  • Mientras se está ejecutando cualquier temporizador, otro podría golpear su intervalo/tiempo de retardo, pero no se ejecutará hasta que el último haya finalizado.
  • Algunos navegadores dan prioridad a los eventos activados por la interacción del usuario, como onclick y onmousemove, en cuyo caso las funciones asociadas a esos eventos se ejecutarán a expensas de la precisión del temporizador.
  • Esto continuará hasta que haya una apertura (no se han llamado anteriormente temporizadores o controladores de eventos que soliciten la ejecución). Solo entonces se ejecutarán las funciones en el código de ejemplo. Nuevamente uno a la vez, con el primero probablemente, pero sin duda ejecutando primero. Además, me atrevo a suponer que algunos navegadores pueden imponer un tiempo de retardo mínimo, lo que haría que cualquier temporizador configurado con un retraso de 0 milisegundos se ejecute incluso más tarde de lo esperado.

Obviamente, no hay una ventaja de rendimiento para ejecutar código como este. En todos los casos, hará que las cosas tarden más en completarse. Sin embargo, en casos en los que una sola tarea demora tanto en congelar el navegador (y posiblemente haga que el script "se esté tomando demasiadas" advertencias del navegador), puede ser útil dividirlo en partes de ejecución más pequeñas que se ejecutan secuencialmente después de un tiempo de retraso , dando así al navegador algo de tiempo para respirar.

Web Workers se han mencionado, y si no le preocupa la compatibilidad de IE, puede usarlos para concurrencia real. Sin embargo, existen algunas limitaciones severas en su uso impuestas por razones de seguridad.Por un lado, no pueden interactuar con el DOM de ninguna manera, lo que significa que cualquier cambio en la página todavía debe hacerse de forma síncrona. Además, todos los datos pasados ​​a y desde los trabajadores se serializan en tránsito, lo que significa que no se pueden usar objetos JavaScript reales. Dicho esto, para el procesamiento intensivo de datos, Web Workers es probablemente una mejor solución que dividir una función en tareas con múltiples temporizadores retrasados.

+0

Sería útil hacer var tId1 = setTimeout (function() {iterateArray (array1); reportDone (1);}, 0); var tId2 = setTimeout (function() {iterateArray (array2); reportDone (2);}, 0); – mplungjan

+0

La única diferencia que veo es la asignación de identificadores de temporizador a las variables. Todos los identificadores del temporizador son realmente buenos para cancelar dichos temporizadores. Un poco sin sentido para los tiempos de espera de 0ms de ejecución una vez. – MooGoo

1

Tengo que estar de acuerdo con MooGoo, también me pregunto por qué se ejecutará una matriz tan grande de una sola vez.

Existe una extensión de JavaScript llamada StratifiedJS, que le permite hacer varias cosas a la vez, siempre que sean asincrónicas. Además, los webworkers son una "solución" incómoda que hace las cosas más complicadas, además, no funcionan en IE.

En StratifiedJS puede escribir.

waitfor { 
    // do something long lasting here... 
} 
and { 
    // do something else at the same time... 
} 
// and when you get here, both are done 
Cuestiones relacionadas