如何使用jquery链接ajax调用

前端之家收集整理的这篇文章主要介绍了如何使用jquery链接ajax调用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要做一系列N ajax请求,而不锁定浏览器,并希望使用jquery deferred对象来完成这个。

这里是一个简单的例子,有三个请求,但我的程序可能需要排队超过100(注意,这不是确切的用例,实际代码确实需要确保步骤(N-1)成功执行下一个步):

$(document).ready(function(){

    var deferred = $.Deferred();

    var countries = ["US","CA","MX"];

    $.each(countries,function(index,country){

        deferred.pipe(getData(country));

    });

 });

function getData(country){

    var data = {
        "country": country  
    };


    console.log("Making request for [" + country + "]");

    return $.ajax({
        type: "POST",url: "ajax.jsp",data: data,dataType: "JSON",success: function(){
            console.log("Successful request for [" + country + "]");
        }
    });

}

这里是写入控制台(所有请求并行进行,响应时间直接与每个国家的数据大小成正比的预期:

Making request for [US]
Making request for [CA]
Making request for [MX]
Successful request for [MX]
Successful request for [CA]
Successful request for [US]

如何获得延迟对象排队这些为我?我试过更改完成管,但得到相同的结果。

这里是所需的结果:

Making request for [US]
Successful request for [US]
Making request for [CA]
Successful request for [CA]
Making request for [MX]
Successful request for [MX]

编辑:

我赞赏使用数组来存储请求参数的建议,但是jquery deferred对象有排队请求的能力,我真的想学习如何使用这个功能的全部潜力。

这实际上是我想做的:

when(request[0]).pipe(request[1]).pipe(request[2])... pipe(request[N]);

但是,我想要将请求分配到管道中,一次一步,以有效地使用每个遍历:

deferred.pipe(request[0]);
deferred.pipe(request[1]);
deferred.pipe(request[2]);

解决方法

使用自定义对象
function DeferredAjax(opts) {
    this.options=opts;
    this.deferred=$.Deferred();
    this.country=opts.country;
}
DeferredAjax.prototype.invoke=function() {
    var self=this,data={country:self.country};
    console.log("Making request for [" + self.country + "]");

    return $.ajax({
        type: "GET",url: "wait.PHP",success: function(){
            console.log("Successful request for [" + self.country + "]");
            self.deferred.resolve();
        }
    });
};
DeferredAjax.prototype.promise=function() {
    return this.deferred.promise();
};


var countries = ["US","MX"],startingpoint = $.Deferred();
startingpoint.resolve();

$.each(countries,function(ix,country) {
    var da = new DeferredAjax({
        country: country
    });
    $.when(startingpoint ).then(function() {
        da.invoke();
    });
    startingpoint= da;
});

小提琴http://jsfiddle.net/7kuX9/1/

为了更清楚,最后一行可以写

c1=new DeferredAjax( {country:"US"} );
c2=new DeferredAjax( {country:"CA"} );
c3=new DeferredAjax( {country:"MX"} );

$.when( c1 ).then( function() {c2.invoke();} );
$.when( c2 ).then( function() {c3.invoke();} );

管道

function fireRequest(country) {
        return $.ajax({
            type: "GET",data: {country:country},success: function(){
                console.log("Successful request for [" + country + "]");
            }
        });
}

var countries=["US",startingpoint=$.Deferred();
startingpoint.resolve();

$.each(countries,country) {
    startingpoint=startingpoint.pipe( function() {
        console.log("Making request for [" + country + "]");
        return fireRequest(country);
    });
});

http://jsfiddle.net/k8aUj/1/

编辑:在结果窗口http://jsfiddle.net/k8aUj/3/输出日志的小提琴

每个管道调用返回一个新的promise,它又用于下一个管道。注意,我只提供sccess功能,应该提供类似的功能失败。

在每个解决方案中,Ajax调用被延迟,直到需要通过将它们包装在一个函数中,并为列表中的每个项目创建一个新的promise来构建链。

我相信自定义对象提供了一个更容易的方式来操纵链,但管道可以更好地适合你的口味。

注意:作为jQuery 1.8,deferred.pipe()已弃用,deferred.then替换它。

猜你在找的jQuery相关文章