Оскільки 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
, ...