因为浏览器中的 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) {
// do a bunch of stuff
if (condition happens to change flag value) {
// call the callback to notify other code
callback();
}
}