Поскольку javascript в браузере является однопоточным (за исключением веб-работников, которые здесь не участвуют), и один поток выполнения javascript выполняется до завершения до того, как другой сможет работать, ваш оператор:
while(flag==false) {}
будет просто работать вечно (или пока браузер не пожалуется на неотзывчивый цикл javascript), страница будет казаться зависшей, и никакой другой javascript никогда не сможет запуститься, поэтому значение флага никогда не может быть изменено.
Для небольшого объяснения: Javascript - это язык, управляемый событиями . Это означает, что он запускает часть Javascript, пока не вернет управление обратно интерпретатору. Затем, только когда он возвращается обратно в интерпретатор, Javascript получает следующее событие из очереди событий и запускает его.
Все вещи, такие как таймеры и сетевые события, проходят через очередь событий. Таким образом, когда срабатывает таймер или поступает сетевой запрос, он никогда не «прерывает» выполняющийся в данный момент Javascript. Вместо этого событие помещается в очередь событий Javascript, а затем, когда текущий запущенный Javascript завершается, следующее событие извлекается из очереди событий, и оно начинает свою очередь.
Итак, когда вы выполняете бесконечный цикл, например while(flag==false) {}
, текущий запущенный Javascript никогда не завершается, и, следовательно, следующее событие никогда не извлекается из очереди событий, и, следовательно, значение flag
никогда не изменяется. Ключевым моментом здесь является то, что Javascript не управляется прерываниями . Когда срабатывает таймер, он не прерывает текущий запущенный Javascript, не запускает какой-либо другой Javascript, а затем позволяет продолжить выполнение текущего Javascript. Он просто помещается в очередь событий, ожидая, пока запущенный в данный момент Javascript не завершит свою очередь запуска.
Что вам нужно сделать, так это переосмыслить, как работает ваш код, и найти другой способ запускать любой код, который вы хотите запустить при flag
изменении значения. Javascript разработан как язык, управляемый событиями. Итак, что вам нужно сделать, так это выяснить, какие события вы можете заинтересовать, чтобы вы могли либо прослушивать событие, которое может вызвать изменение флага, и вы можете проверить флаг этого события, либо вы можете инициировать собственное событие из любой код может изменить флаг, или вы можете реализовать функцию обратного вызова, которая при любых изменениях кода в этом флаге может вызывать ваш обратный вызов всякий раз, когда фрагмент кода, ответственный за изменение значения флага, изменит его значение,true
, он просто вызывает функцию обратного вызова и, следовательно, ваш код который хочет работать, когда флаг установлен наtrue
побегут в нужное время. Это намного, намного эффективнее, чем пытаться использовать какой-то таймер для постоянной проверки значения флага.
function codeThatMightChangeFlag(callback) {
if (condition happens to change flag value) {
callback();
}
}
jQuery.Deferred
,Q
,async
, ...