5

我仅在 setTimeout 回调中设置变量后才尝试返回变量。我想不出任何其他方法来做到这一点,但这是我的尝试(我知道代码看起来很傻,但它是为了解决 Cordova 错误)。由于我无法理解的原因,它会导致无限循环。

function isConnected() {
    var done = false;
    setTimeout(function() {
        done = true;
    }, 500);

    while (!done) {}
    return navigator.connection.type!== Connection.NONE;
}

谁能向我解释为什么会发生这种情况,或提供替代方案?

更新(解决方案):

function isConnected(callback) {
    setTimeout(function() {     
        callback(navigator.connection.type !== Connection.NONE);
    }, 500);
}


isConnected(function(connected) {
    if (!connected)
        alert('Not Connected');
});
4

3 回答 3

7

你根本不能那样解决你的问题。因为 javascript 是单线程的,所以 setTimeout 回调只能在您的 JS 执行线程完成时运行,因此对于您的无限循环,它永远不会运行并且您的代码将挂起。最终浏览器会抱怨一段长时间运行的 JS 并提出关闭它。

相反,您需要在 上使用回调函数setTimeout()并从该回调继续您的代码。您不能将顺序代码用于超时。您必须使用异步编码样式。

你可以做这样的事情,你传入一个回调,它调用回调并将连接的布尔值传递给它:

function GetConnectedState(callback) {

    setTimeout(function() {     
        callback(navigator.connection.type !== Connection.NONE);
    }, 500);

}

除了在 1/2 秒内查看连接状态之外,您现有的代码似乎没有提供任何其他功能。对于 javascript 中的任何真正类型的异步操作(例如 ajax 调用或 websocket 连接),还应该有一个成功或完成回调,它会告诉您操作何时/是否实际完成,您还可以基于触发回调那个(大部分时间不到 1/2 秒)。所以,这看起来并不像一个完整的解决方案,但它是您向我们展示的所有您正在使用的解决方案。

例如,您可以查看以下答案,当图像加载成功、出现错误或超时且无响应时调用回调:Javascript Image Url Verify and How to implement a "function timeout" in Javascript - 而不仅仅是'设置超时'。类似的概念可用于在某些其他类型的异步调用上实现您自己的超时。

于 2013-11-14T19:27:39.167 回答
6

当我在 5 年后重新审视这个时,不禁要提供一个更好的选择:

await new Promise(function(resolve) {
  setTimeout(resolve, 500);
});
if (navigator.connection.type === Connection.NONE) {
  alert('Not Connected');
}
于 2018-08-13T08:18:31.260 回答
4

Javascript是单线程的。在您的脚本返回到主事件循环之前,超时函数无法运行。但只要你在while循环中,它就永远不会返回,所以 timeout 函数永远不会运行,所以done永远不会设置为true.

在 Javascript 中不可能在返回之前等待异步事件。

于 2013-11-14T19:24:56.190 回答