用jQuery延迟链接ajax请求

我有一个Web应用程序,必须多次调用服务器。 到目前为止,我有一个很长的嵌套回调链; 但我想使用jQuery的when ,等等function。 但是,在使用then之后,我似乎无法再次运行。

 $ .when ($.get('pages/run-tool.html')) .then (function (args) { // This works fine alert(args); $('#content').replaceWith (args); $('#progress-bar').progressbar ({value: 0}); }) .then ($.get('pages/test.html')) .done (function(args) { // This prints the same as the last call alert (args); }); 

我究竟做错了什么? 我猜它有一些范围问题,因为我可以看到正在执行的第二个调用。 使用两个不同的args变量没有帮助,因为传递给done函数的参数仍然是第一个get请求。

作为更新:

使用现代jquery(1.8+),你不需要初步的时候因为get返回Deferred Promise。

此外,不推荐使用管道然后使用。 只需确保返回新get的结果,该结果将成为随后的/ * done * / fail调用附加的Promise。

所以:

 $.get('pages/run-tool.html') .then (function (args) { // this will run if the above .get succeeds // This works fine alert(args); $('#content').replaceWith (args); $('#progress-bar').progressbar ({value: 0}); }) .then (function() { // this will run after the above then-handler (assuming it ran) return $.get('pages/test.html'); // the return value creates a new Deferred object }) .done (function(args) { // this will run after the second .get succeeds (assuming it ran) alert (args); }); 

所有三个回调(两个带有then和带有done回调)都应用于同一个请求 – 调用when的原始请求。 这是因为then返回相同的Deferred对象而不是新对象,以便您可以添加多个事件处理程序。

你需要使用pipe

 $ .when ($.get('pages/run-tool.html')) .then (function (args) { // This works fine alert(args); $('#content').replaceWith (args); $('#progress-bar').progressbar ({value: 0}); }) .pipe (function() { return $.get('pages/test.html'); // the return value creates a new Deferred object }) .done (function(args) { alert (args); }); 

这是一个非常简单和高效的AJAX链接/队列插件。 它会一个接一个地按顺序执行ajax方法。

它的工作原理是接受一组方法,然后按顺序执行它们。 它在等待响应时不会执行下一个方法。

// —这部分是你的代码———————–

$(document).ready(function(){

 var AjaxQ = []; AjaxQ[0] = function () { AjaxMethod1(); } AjaxQ[1] = function () { AjaxMethod2(); } AjaxQ[3] = function () { AjaxMethod3(); } //Execute methods in sequence $(document).sc_ExecuteAjaxQ({ fx: AjaxQ }); 

});

// —这部分是AJAX PLUGIN ——————-

$ .fn.sc_ExecuteAjaxQ = function(options){

 //? Executes a series of AJAX methods in dequence var options = $.extend({ fx: [] //function1 () { }, function2 () { }, function3 () { } }, options); if (options.fx.length > 0) { var i = 0; $(this).unbind('ajaxComplete'); $(this).ajaxComplete(function () { i++; if (i < options.fx.length && (typeof options.fx[i] == "function")) { options.fx[i](); } else { $(this).unbind('ajaxComplete'); } }); //Execute first item in queue if (typeof options.fx[i] == "function") { options.fx[i](); } else { $(this).unbind('ajaxComplete'); } } 

}

目前投票率最高的cdr给出的答案是不对的。

当你有函数a,b,c时,每个函数返回一个$ .Deferred()对象,并将函数链接如下:

 a().then(b).then(c) 

一旦从a返回的promise被解析,b和c都将运行。 由于then()函数都与a的promise相关联,因此与其他Jquery链接类似,例如:

 $('#id').html("
hello
").css({display:"block"})

从$(’#id’)返回的对象上调用html()和css()函数;

因此,要在解析从前一个函数返回的promise之后运行a,b,c,您需要执行以下操作:

 a().then(function(){ b().then(c) }); 

这里函数c的调用与函数b返回的promise相关联。

您可以使用以下代码对此进行测试:

 function a() { var promise = $.Deferred(); setTimeout(function() { promise.resolve(); console.log("a"); }, 1000); return promise; } function b() { console.log("running b"); var promise = $.Deferred(); setTimeout(function () { promise.resolve(); console.log("b"); }, 500); return promise; } function c() { console.log("running c"); var promise = $.Deferred(); setTimeout(function () { promise.resolve(); console.log("c"); }, 1500); return promise; } a().then(b).then(c); a().then(function(){ b().then(c) }); 

将函数b()中的promise从resolve()更改为reject(),您将看到差异。

  

我想我会把这个小练习留给任何可能觉得有用的人,我们构建一系列请求,当它们完成后,我们可以触发一个回调函数:

 var urls = [{ url: 'url1', data: 'foo' }, { url: 'url2', data: 'foo' }, { url: 'url3', data: 'foo' }, { url: 'url4', data: 'foo' }]; var requests = []; var callback = function (result) { console.log('done!'); }; var ajaxFunction = function () { for (var request, i = -1; request = urls[++i];) { requests.push($.ajax({ url: request.url, success: function (response) { console.log('success', response); } })); } }; // using $.when.apply() we can execute a function when all the requests // in the array have completed $.when.apply(new ajaxFunction(), requests).done(function (result) { callback(result) }); 

我的方法是应用回调函数:

 A(function(){ B(function(){ C()})}); 

其中A,B可写为

 function A(callback) $.ajax{ ... success: function(result){ ... if (callback) callback(); } }