Ponieważ javascript w przeglądarce jest jednowątkowy (z wyjątkiem webworkerów, którzy nie są tutaj zaangażowani), a jeden wątek wykonywania javascript działa do końca, zanim inny będzie mógł zostać uruchomiony, Twoja instrukcja:
while(flag==false) {}
będzie po prostu działać w nieskończoność (lub dopóki przeglądarka nie będzie narzekać na nieodpowiadającą pętlę javascript), strona będzie wyglądać na zawieszoną i żaden inny javascript nigdy nie będzie miał szansy na uruchomienie, więc wartość flagi nigdy nie może zostać zmieniona.
Aby uzyskać więcej wyjaśnień, JavaScript jest językiem sterowanym zdarzeniami . Oznacza to, że uruchamia fragment JavaScript, dopóki nie zwróci kontroli z powrotem do interpretera. Następnie, dopiero po powrocie do interpretera, Javascript pobiera następne zdarzenie z kolejki zdarzeń i uruchamia je.
Wszystkie rzeczy, takie jak liczniki czasu i zdarzenia sieciowe, przechodzą przez kolejkę zdarzeń. Tak więc, gdy uruchamia się licznik czasu lub przychodzi żądanie sieciowe, nigdy nie „przerywa” aktualnie działającego JavaScript. Zamiast tego zdarzenie jest umieszczane w kolejce zdarzeń Javascript, a następnie, po zakończeniu aktualnie działającego kodu JavaScript, następne zdarzenie jest pobierane z kolejki zdarzeń i wykonuje swoją kolej.
Tak więc, gdy wykonujesz nieskończoną pętlę, taką jak while(flag==false) {}
aktualnie działający JavaScript, nigdy się nie kończy, a zatem następne zdarzenie nigdy nie jest pobierane z kolejki zdarzeń, a zatem wartość flag
nigdy nie jest zmieniana. Kluczowe jest tutaj to, że Javascript nie jest sterowany przerwaniami . Uruchomiony licznik czasu nie przerywa aktualnie uruchomionego Javascript, nie uruchamia innego Javascript, a następnie pozwala kontynuować aktualnie działający Javascript. Po prostu zostaje umieszczony w kolejce zdarzeń, czekając, aż aktualnie działający Javascript zakończy swoją kolej.
To, co musisz zrobić, to przemyśleć, jak działa twój kod i znaleźć inny sposób wyzwalania dowolnego kodu, który chcesz uruchomić, gdy flag
zmieni się wartość. JavaScript jest zaprojektowany jako język sterowany zdarzeniami. Więc to, co musisz zrobić, to dowiedzieć się, jakie zdarzenia możesz zarejestrować, abyś mógł albo nasłuchiwać zdarzenia, które może spowodować zmianę flagi, i możesz sprawdzić flagę tego zdarzenia lub wyzwolić własne zdarzenie z jakikolwiek kod może zmienić flagę lub możesz zaimplementować funkcję zwrotną, która niezależnie od tego, czy kod zmieni tę flagę, może wywołać wywołanie zwrotne za każdym razem, gdy fragment kodu odpowiedzialny za zmianę wartości flagi zmieni jej wartość true
, po prostu wywoła funkcję zwrotną, a tym samym twój kod który chce działać, gdy flaga zostanie ustawiona natrue
zacznie działać we właściwym czasie. Jest to dużo, dużo bardziej wydajne niż próba użycia jakiegoś timera do ciągłego sprawdzania wartości flagi.
function codeThatMightChangeFlag(callback) {
if (condition happens to change flag value) {
callback();
}
}
jQuery.Deferred
,Q
,async
, ...