5

请看下面的代码,你觉得会先打印哪个日志?
在 Chrome 和 IE 中,首先显示“同步 ajax 调用:成功”,这是预期的,
但在 FF 中(在 FF 3.6 和 FF 17.0 中测试),首先显示“异步 ajax 调用:成功”,
这意味着虽然我们使第二个作为同步调用,但是当它的onreadystatechange被触发时,异步(第一)ajax调用的处理程序比同步(第二)ajax调用的处理程序执行得早,这有意义吗?
不是firefox的bug吗?

// first ajax call, Note: this is asynchronous.
$.ajax({
    url: "/rest/someUrl",
    async : true,
    dataType : "json",
    contentType: "application/json",
    success : function(data) {
        console.log("async ajax call: success");
    },
    error : function(data) {
    }
})
// second ajax call, Note: this is synchronous.
$.ajax({
    url: "/rest/someUrl",
    async : false,
    dataType : "json",
    contentType: "application/json",
    success : function(data) {
        console.log("sync ajax call: success");
    },
    error : function(data) {
    }
})
4

1 回答 1

5

要“正确”实现某些东西,必须有一些规范。

在规范中,我没有找到任何关于只要同步请求未完成,所有脚本都应该停止执行的事实(请注意,当 sync-XHR 启动时 async-XHR 已经在运行)。

但我发现了这个:

  1. 每个 XMLHttpRequest 对象都有自己的任务源。即 XMLHttpRequest 任务源。
    --两个请求都代表一个任务源--

  2. 当用户代理要对任务进行排队时,它必须将给定任务添加到相关事件循环的任务队列之一。[...] 来自不同任务源的任务可能被放置在不同的任务队列中。
    --两个任务可以添加到同一个任务队列中,但不能--

  3. 只要事件循环存在,它就必须不断地运行以下步骤:
    1.在事件循环的任务队列之一上运行最旧的任务,如果有的话,[...]。用户代理可以选择任何任务队列。

    --他现在选择了他放置同步请求的任务队列

当我没有误解这一点并且我的逻辑没有错时,这可能会发生:

Firefox 将 XHR 放在同一个队列中,IE 和 chrome 将它们放在不同的任务队列中。

所有浏览器现在都运行他们放置同步 XHR 的任务队列。

  • 在 IE 和 chrome 中,同步 XHR 是他队列中最旧的任务并运行
  • 在 FF 中,异步 XHR 在他的队列中是最老的并且运行

两种实现似乎都是正确的。

于 2013-01-11T08:35:18.633 回答