一尘不染

等到flag = true

javascript

我有这样的javascript函数:

function myFunction(number) {

    var x=number;
    ...
    ... more initializations
    //here need to wait until flag==true
    while(flag==false)
    {}

    ...
    ... do something

}

问题是javascript卡在了一段时间,卡住了我的程序。所以我的问题是我如何才能在函数中间等待直到标志为真,而无需“忙等待”?


阅读 328

收藏
2020-05-01

共1个答案

一尘不染

由于浏览器中的javascript是单线程的(webworkers除外,此处未涉及),并且其中一个javascript执行线程在另一个线程可以运行之前运行完毕。

while(flag==false) {}

将会永久运行(或直到浏览器抱怨无响应的javascript循环),该页面似乎已被挂起,并且没有其他javascript可以运行,因此该标志的值永远不会更改。

为了进一步说明, Javascript是一种事件驱动语言
。这意味着它将运行一段Javascript,直到将控制权返回给解释器。然后,只有当它返回解释器时,Javascript才会从事件队列中获取下一个事件并运行它。

计时器和网络事件之类的所有东西都贯穿事件队列。因此,当计时器触发或网络请求到达时,它永远不会“中断”当前正在运行的Javascript。而是将事件放入Javascript事件队列中,然后,当当前正在运行的Javascript完成时,将下一个事件从事件队列中拉出,然后轮流运行。

因此,当您执行无限循环(例如)时while(flag==false) {},当前运行的Javascript将永远不会完成,因此下一个事件也不会从事件队列中拉出,因此no的值flag永远不会改变。他们的关键是
Javascript不是中断驱动的

。计时器触发时,它不会中断当前正在运行的Javascript,不会运行其他一些Javascript,然后继续运行当前正在运行的Javascript。只是将其放入事件队列中,等待当前运行的Java脚本运行完毕。


您需要做的是重新考虑代码的工作方式,并找到另一种方法来在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();
    }
}
2020-05-01