在 javascript 中,您不能循环等待条件更改,除非实际更改条件的代码位于该循环内部或循环中调用的某些函数的副作用。这是因为 javascript 是单线程的(除了这里没有考虑的 webworkers ),所以只要 javascript 中存在一个循环,就没有其他代码可以运行,因此没有其他代码可以更改您的条件变量。你只会有一个无限循环,因为循环等待永远不会改变的东西。最终浏览器会抱怨您正在运行无响应的代码并将其关闭。
因此,JavaScript 中不存在不确定或长时间的等待循环。可以循环一秒钟左右,只是为了让时间过去,但这很少有用、高效,也不是编写 JS 代码的最佳方式。
相反,当条件发生变化时,您必须触发事件或回调,并且感兴趣的代码可以订阅该事件或注册其回调。或者,您必须轮询计时器以查看条件发生了什么变化(第一个选项是首选)。
如果您正在设计一个 API,希望能够允许某些调用代码知道状态何时发生变化,通常您会实现回调或承诺。回调方法可能如下所示:
device.registerStateChangeCallback("type of state interested in", fn);
然后,每当指定的状态更改为新值时,API 就会调用传入的回调函数。这是一次性通知还是每次状态更改时都会发生直到取消注册回调,由 API 决定。
因此,调用者不是让调用者在繁忙的循环中等待直到状态发生变化,而是编写带有回调的异步代码(这就是 JavaScript 处理此类内容的方式),该回调将在状态发生变化时调用。例如,调用者的代码可能如下所示:
device.registerStateChangeCallback("syncState", function(newState) {
// caller puts code here that wants to do something when
// the syncState has changed
});
如果通知只是一次,那么您还可以使用 Promise,并且 API 只返回一个 Promise,该 Promise 在syncState 更改时得到解决:
device.registerStateChange("syncState").then(function(newState) {
// caller puts code here that wants to do something when
// the syncState has changed
});
Promise 的缺点是它们纯粹是一次性使用(仅一个通知),因此如果您想要多个通知,那么最好使用回调。 Promise 相对于回调的优点在于,它们提供了许多用于将它们与其他事件同步的功能(例如排序、等待一系列事件全部完成、协调多个异步事物等),并且它们提供了更好的异步功能错误处理。