我有这样的javascript函数:
function myFunction(number) {
var x=number;
...
... more initializations
//here need to wait until flag==true
while(flag==false)
{}
...
... do something
}
问题是javascript被困在了一段时间并且卡住了我的程序.所以我的问题是我怎么能在函数中间等待,直到flag为真而没有“忙等待”?
解决方法:
因为浏览器中的javascript是单线程的(除了这里没有涉及的webworkers),并且javascript执行的一个线程在另一个可以运行之前运行完成,你的语句:
while(flag==false) {}
将永远运行(或直到浏览器抱怨无响应的javascript循环),页面将显示为挂起,没有其他javascript将有机会运行,因此标志的值永远不会被更改.
对于更多解释,Javascript是一种事件驱动的语言.这意味着它运行一段Javascript,直到它将控制权返回给解释器.然后,只有当它返回到解释器时,Javascript才从事件队列中获取下一个事件并运行它.
计时器和网络事件等所有内容都通过事件队列运行.因此,当计时器触发或网络请求到达时,它不会“中断”当前运行的Javascript.相反,一个事件被放入Javascript事件队列中,然后,当当前运行的Javascript完成时,下一个事件将从事件队列中拉出并轮到它运行.
因此,当你执行诸如while(flag == false){}之类的无限循环时,当前运行的Javascript永远不会完成,因此下一个事件永远不会从事件队列中拉出,因此flag的值永远不会被更改.它们的关键在于Javascript不是中断驱动的.当计时器触发时,它不会中断当前运行的Javascript,运行其他一些Javascript,然后让当前运行的Javascript继续.它只是放入事件队列中等待,直到当前运行的Javascript完成以轮到它运行.
您需要做的是重新考虑代码的工作方式,并找到一种不同的方法来触发标志值更改时要运行的代码. 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();
}
}