Firefox似乎正在排队等待并行ajax请求的成功函数,可能是因为setTimeout



查看这篇文章

http://jsfiddle.net/PRqZg/

<div class="colors" id="section_1"></div>
<div class="colors" id="section_2"></div>
<div class="colors" id="section_3"></div>
<div class="colors" id="section_4"></div>
<div class="colors" id="section_5"></div>
<div class="colors" id="section_6"></div>
<div class="colors" id="section_7"></div>
<div class="colors" id="section_8"></div>
<div class="colors" id="section_9"></div>
<div class="colors" id="section_10"></div>

JS

function doAjax(i)
{   
    var data = {json:"{"x": 1}"};
    $.ajax({
        url:"/echo/json/",
        data:"json"     
    })
    .done(function(result){
        $('#section_'+i).toggleClass('color2');         
    })          
    .always(function(){     
        setTimeout(function(){doAjax(i)}, 500);
    });
}
$(document).ready(function(){
    var obs = $('.colors');
    for(i = 0;i <= obs.length;i++)
    {
        doAjax(i);
    };
});
CSS

.colors {display:inline-block;width:100%;height:40px;border:1px solid #000;}
.color2 {background:red;}

我把它分解成我能想到的最简单的例子。我的终端软件将需要为页面上的每个元素运行一个反复出现的单独ajax请求,所以我现在不能考虑将其全部集中到一个请求中。

所以在我的小提琴,我做了7个简单的div,只是想在成功的ajax请求后切换一个类,因此我的简单的例子。在chrome中,正如我所期望的那样,因为请求是异步的,所有的div同时切换类(或者至少接近到足以欺骗人眼)。这甚至可以在IE中工作(尽管有一点延迟,我注意到一个闪烁的点)。

然而,在firefox中,似乎每个ajax请求的done()函数直到前一个完成才触发。经过一番研究,我甚至发现firefox可以在开始排队之前同时运行6个对同一台主机的并发请求。但似乎这应该产生小提琴中呈现的结果,但在每六个请求而不是每一个请求的规模上。同样,如果我将div的数量减少到6以下,我也会观察到相同的行为。

这是firefox的bug还是我错过了什么?因为如果这是它的默认性能,考虑到所做的一切都是切换类,这似乎很糟糕。

事实证明Firefox有一个非常愚蠢的行为,它使ajax请求排队到完全相同的url,以便他们的成功函数一个接一个地被触发。解决这个问题的方法是向ajx url本身附加一个随机变量数。我不确定这是一个奇怪的行为背后的变通方法,还是仅仅是由于firefox的缓存方法所必需的。

注意:我实际上是以1秒/100为单位传递时间戳的,所以如果你有一个东西每十分之一秒触发一次以上,你需要将时间戳除以一个更小的值。

修改js为:

function doAjax(i)
{   
    var data = {json:"{"x": 1}"};
    var rand = new Date().getTime() / 100;
    $.ajax({
        url:"/echo/json/?rand="+rand,
        data:"json"     
    })
    .done(function(result){
        $('#section_'+i).toggleClass('color2');         
    })          
    .always(function(){     
        setTimeout(function(){doAjax(i)}, 500);
    });
}
$(document).ready(function(){
    var obs = $('.colors');
    for(i = 0;i <= obs.length;i++)
    {
        doAjax(i);
    };
});

参见下面的示例:http://jsfiddle.net/Zv2R2/1/

最新更新