提问者:小点点

在while循环中等待外部变量更改或事件?


我对whileloop有疑问

我需要等到while循环之外的东西发生变化。

假设我有一个while循环:

window.changeMe = true;
while(window.changeMe){

}

现在我有这两个选择:

  1. 通过控制台/JavaScript执行更改changeme变量
  2. 通过WebSocket事件更改changeme变量

但两者都不起作用,如果我直接改变变量,它就不变了。如果我触发了一个WebSocket事件,它就不会被调用。可能它的被阻止.。那么有没有其他方法可以改变变量呢?

我知道我可以使用await,而且它已经这样工作了,但问题是while的这些函数是通过一个插件调用的,使用许多await对于插件创建者来说看起来有点难看:(


共3个答案

匿名用户

JavaScript是单线程的。如果您有while(true){},则while循环之外的任何其他东西都无法更改程序的状态。你需要改变你的方法。您可能希望设置事件侦听器,或者将其放在async函数中,以便可以使用await释放执行,或者使用其他异步API。但是plain vanillawhile(){}是同步的,在运行时不能受到其他东西的影响。

匿名用户

是的,你是对的。拥有一个无限的while循环将阻止从占据主线程的javascript事件循环执行任何其他代码。

为了模仿相同的行为,您可以实现自己的while循环,该循环对异步事件和外部代码执行很友好。您必须使用:

  • 尾递归以便最小化内存占用,
  • 设置Timeout作为允许代码的其他部分异步运行的机制。

示例:

window.changeMe = true;

let stop = setTimeout(() => { console.log("External change stop"); window.changeMe = false; }, 4000)

var whileLoop = () => {

  console.log("Inside: ", window.changeMe)
  
  return window.changeMe
    ? setTimeout(() => { whileLoop(); }, 0)
    : false

}

whileLoop()

console.log("Outside: ", window.changeMe)

下面是一个小提琴:https://jsfiddle.net/qwmosfrd/

匿名用户

在NodeJS中不能以这种方式使用while循环。

Nodejs在单个线程中运行Javascript,环境的整体架构是事件驱动的。您的while循环所做的是一个自旋循环,因此当该循环运行时,任何其他事件都无法运行。在运行任何其他事件之前,您必须将控制权返回给事件循环。这意味着计时器,网络事件等。。。旋转循环正在运行时无法运行。因此,在nodejs中,这永远不是编写代码的正确方式。这是行不通的。

一个例外可能是循环中有一个await,它会暂停循环并允许其他事件运行。

因此,在运行时:

while(window.changeMe){

}

没有其他事件可以运行,因此没有其他事件有机会更改ChangeMe属性。因此,这只是一个无限循环,永远无法完成,其他任何东西都没有机会运行。

相反,您希望将体系结构更改为事件驱动的,这样,无论ChangeMe属性发生什么变化,都会发出某种其他代码可以侦听的事件,以便在发生变化时得到通知。这可以通过使更改属性的特定代码也通知侦听器来实现,也可以通过使属性成为setter方法来实现,以便该方法可以看到属性正在更改,并可以激发一个事件来通知任何感兴趣的侦听器值已更改。