如何链使用jQuery Ajax调用 [英] How to chain ajax calls using jquery

查看:123
本文介绍了如何链使用jQuery Ajax调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要做一个N系列Ajax请求不锁定浏览器,并希望使用jQuery的Deferred对象做到这一点。

下面是一个有三个请求,一个简单的例子,但我的程序可能需要排队超过100(注意,这是不准确的使用情况下,实际code确实需要确保一步的成功(N- 1)在执行下一个步骤)之前:

  $(文件)。就绪(函数(){

    VAR推迟= $ .Deferred();

    VAR国家=美国,CA,MX];

    $每个(国家,函数(指数,国家){

        deferred.pipe(的getData(国家));

    });

 });

功能的getData(国家){

    VAR数据= {
        国:国
    };


    的console.log(使请求[+国家+]);

    返回$阿贾克斯({
        键入:POST,
        网址:ajax.jsp
        数据:数据,
        数据类型:JSON,
        成功:函数(){
            的console.log(成功请求[+国家+]);
        }
    });

}
 

下面是获取写入到控制台(所有请求都被制成平行且响应时间成正比,各国家的数据的预期的尺寸:

 的[美]制作要求
用于制作要求[CA]
用于制作要求[MX]
成功请求[MX]
成功请求[CA]
成功请求[美国]
 

我怎样才能获得延期对象来排队这些了我吗?我试图改变做管道,但得到了同样的结果。

下面是所期望的结果:

 的[美]制作要求
成功请求[美国]
用于制作要求[CA]
成功请求[CA]
用于制作要求[MX]
成功请求[MX]
 

编辑:

我AP preciate建议使用数组存储请求参数,但jQuery的延迟对象必须排队请求的能力,我真的想学习如何使用此功能,充分发挥其潜力。

这实际上是我想要做的:

 时(请求[0])管(要求[1])管(请求[2])...管道(要求[N])。;
 

不过,我想,以有效地利用每一个遍历分配请求进入管一步步来:

  deferred.pipe(请求[0]);
deferred.pipe(请求[1]);
deferred.pipe(请求[2]);
 

解决方案

使用自定义对象

 函数DeferredAjax(选){
    this.options =选择采用;
    this.deferred = $递延()。
    this.country = opts.country;
}
DeferredAjax.prototype.invoke =功能(){
    无功自我=这一点,数据= {国家:self.country};
    的console.log(使请求[+ self.country +]);

    返回$阿贾克斯({
        键入:GET,
        网址:wait.php
        数据:数据,
        数据类型:JSON,
        成功:函数(){
            的console.log(成功请求[+ self.country +]);
            self.deferred.resolve();
        }
    });
};
DeferredAjax.prototype.promise =功能(){
    返回this.deferred.promise();
};


VAR国家=美国,CA,MX],起点= $ .Deferred();
startingpoint.resolve();

$每个(国家,函数(九,国家){
    VAR DA =新DeferredAjax({
        国家:国家
    });
    $。当(起点)。然后(函数(){
        da.invoke();
    });
    起点= DA;
});
 

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

要有点更清晰,最后几行可以写成

  C1 =新DeferredAjax({国家:美国});
C2 =新DeferredAjax({国家:CA});
C3 =新DeferredAjax({国家:MX});

$。当(C1)。然后(函数(){c2.invoke();});
$。当(C2)。然后(函数(){c3.invoke();});
 

随着管道

 函数fireRequest(国家){
        返回$阿贾克斯({
            键入:GET,
            网址:wait.php
            数据:{国家:国家},
            数据类型:JSON,
            成功:函数(){
                的console.log(成功请求[+国家+]);
            }
        });
}

。VAR国家=美国,CA,MX],起点= $递延();
startingpoint.resolve();

$每个(国家,函数(九,国家){
    起点= startingpoint.pipe(函数(){
        的console.log(使请求[+国家+]);
        返回fireRequest(国家);
    });
});
 

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

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

每个管调用返回一个新的承诺,后者又用于下一管。注意,我只提供的sccess功能,类似的功能应被提供用于故障。

在每个解决方案中,Ajax调用延迟到需要它们包裹在一个函数和一个新的承诺是根据每个项目在列表中创建打造的产业链。

我相信,自定义对象提供了一个简单的方法来操纵链,但管道能更好地满足您的口味。

注意:对于jQuery 1.8, deferred.pipe() 是德precated, deferred.then 替换它。

I need to make a series of N ajax requests without locking the browser, and want to use the jquery deferred object to accomplish this.

Here is a simplified example with three requests, but my program may need to queue up over 100 (note that this is not the exact use case, the actual code does need to ensure the success of step (N-1) before executing the next step):

$(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 + "]");
        }
    });

}

Here is what gets written into the console (all requests are made in parallel and the response time is directly proportional to the size of the data for each country as expected:

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

How can I get the deferred object to queue these up for me? I've tried changing done to pipe but get the same result.

Here is the desired result:

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

Edit:

I appreciate the suggestion to use an array to store request parameters, but the jquery deferred object has the ability to queue requests and I really want to learn how to use this feature to its full potential.

This is effectively what I'm trying to do:

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

However, I want to assign the requests into the pipe one step at a time in order to effectively use the each traversal:

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

解决方案

With a custom object

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",
        data: data,
        dataType: "JSON",
        success: function(){
            console.log("Successful request for [" + self.country + "]");
            self.deferred.resolve();
        }
    });
};
DeferredAjax.prototype.promise=function() {
    return this.deferred.promise();
};


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

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

Fiddle http://jsfiddle.net/7kuX9/1/

To be a bit more clear, the last lines could be written

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();} );

With pipes

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

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

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

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

Edit : A fiddle outputting the log in the result window http://jsfiddle.net/k8aUj/3/

Each pipe call returns a new promise, which is in turn used for the next pipe. Note that I only provided the sccess function, a similar function should be provided for failures.

In each solution, the Ajax calls are delayed until needed by wrapping them in a function and a new promise is created for each item in the list to build the chain.

I believe the custom object provides an easier way to manipulate the chain, but the pipes could better suit your tastes.

Note : as of jQuery 1.8, deferred.pipe() is deprecated, deferred.then replaces it.

这篇关于如何链使用jQuery Ajax调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆