Debido a que javascript en un navegador es de un solo hilo (excepto para los webworkers que no están involucrados aquí) y un hilo de ejecución de javascript se ejecuta hasta su finalización antes de que otro pueda ejecutarse, su declaración:
while(flag==false) {}
simplemente se ejecutará para siempre (o hasta que el navegador se queje de un bucle javascript que no responde), la página parecerá estar colgada y ningún otro javascript tendrá la oportunidad de ejecutarse, por lo que el valor de la bandera nunca se puede cambiar.
Para una explicación más detallada, Javascript es un lenguaje impulsado por eventos . Eso significa que ejecuta una parte de Javascript hasta que devuelve el control al intérprete. Luego, solo cuando regresa al intérprete, Javascript obtiene el siguiente evento de la cola de eventos y lo ejecuta.
Todas las cosas, como los temporizadores y los eventos de la red, se ejecutan en la cola de eventos. Por lo tanto, cuando se activa un temporizador o llega una solicitud de red, nunca "interrumpe" el Javascript que se está ejecutando actualmente. En cambio, un evento se coloca en la cola de eventos de Javascript y luego, cuando finaliza el Javascript que se está ejecutando actualmente, el siguiente evento se extrae de la cola de eventos y tiene su turno para ejecutarse.
Entonces, cuando haces un ciclo infinito como while(flag==false) {}
, el Javascript que se está ejecutando actualmente nunca termina y, por lo tanto, el siguiente evento nunca se extrae de la cola de eventos y, por lo tanto, el valor de flag
nunca cambia. La clave aquí es que Javascript no está controlado por interrupciones . Cuando se activa un temporizador, no interrumpe el Javascript que se está ejecutando actualmente, ejecuta algún otro Javascript y luego deja que el Javascript que se está ejecutando actualmente continúe. Simplemente se coloca en la cola de eventos esperando hasta que el Javascript que se está ejecutando actualmente esté listo para que se ejecute su turno.
Lo que debe hacer es repensar cómo funciona su código y encontrar una forma diferente de activar cualquier código que desee ejecutar cuando flag
cambie el valor. Javascript está diseñado como un lenguaje impulsado por eventos. Entonces, lo que debe hacer es averiguar en qué eventos puede registrar un interés para que pueda escuchar el evento que podría causar que la bandera cambie y pueda examinar la bandera en ese evento o puede activar su propio evento desde cualquier código podría cambiar la bandera o puede implementar una función de devolución de llamada en la que cualquier código que cambie esa bandera puede llamar a su devolución de llamada siempre que el fragmento de código responsable de cambiar el valor de la bandera cambie su valor a true
, solo llama a la función de devolución de llamada y, por lo tanto, su código que quiere correr cuando la bandera se pone entrue
llegará a ejecutarse en el momento adecuado. Esto es mucho, mucho más eficiente que intentar usar algún tipo de temporizador para verificar constantemente el valor de la bandera.
function codeThatMightChangeFlag(callback) {
if (condition happens to change flag value) {
callback();
}
}
jQuery.Deferred
,Q
,async
, ...