【问题标题】:Can a callback to a finished XmlHttpRequest trigger before the send-function is complete?可以在发送函数完成之前对已完成的 XmlHttpRequest 触发回调吗?
【发布时间】:2012-03-18 04:18:51
【问题描述】:

我刚刚注意到我在安装 Firefox 11 后的 web 应用上出现了一些奇怪的行为。我以前没有看到过这个错误,并且该网站已经运行了一年多。

var timeOutTimer = null;

var StartDownload = function () {
    xhr.open("GET", "/Download", true);           //Notice asynchronous=true
    xhr.onreadystatechange = DownloadComplete;
    xhr.send("...");

    timeOutTimer = new Timer(......);   //This line gets executed AFTER DownloadComplete()
};

var DownloadComplete = function () {
    if (xhr.readyState == 4) {
        timeOutTimer.Abort();           //<--------timeOutTimer is null here
        //Callstack points back to xhr.send
    }
}

XmlHttpRequest 真的可以在退出 send() 函数之前调用 onreadystatechange-callback 吗?

仅当我在本地开发服务器上浏览网站时才会出现此错误。此外,如果我添加 1 秒延迟服务器端,则没有问题。我没有在任何其他浏览器中尝试过。

我想解决方案是在发送之前启动计时器,但我只想知道这种行为背后的原因以及是否可以,因为我以前从未经历过。

【问题讨论】:

  • 您是在重新初始化现有的 XHR 对象,还是在每次调用 StartDownload 时创建一个新对象?您的代码中有任何alert() 调用吗?

标签: javascript firefox xmlhttprequest


【解决方案1】:

您说“甚至在退出 send() 函数之前”,但这不是真的。您正在调用发送,然后您正在构建一个计时器,但是事情发生得如此之快,以至于在您将计时器放入其变量之前,回调就发生了。它是异步的,就像你要求的那样。只需要为此做好准备。

【讨论】:

  • 但是 javascript 本身是单线程的。异步事件只能在用户代码未运行时触发。因此 StartDownload 应该在任何异步事件触发之前完成,并且上述行为的唯一方法是如果 send 永远不会退出。
  • 也许这取决于“跑步”的定义——显然你看到了一些令人惊讶的东西,但 FF11 是全新的,所以谁知道呢。正如您所说,如果您移动计时器构造函数,您将是安全的。仍然感到惊讶,但安全。
猜你喜欢
  • 2016-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多