我有一个必须多次调用服务器的Web应用程序。到目前为止,我有一个很长的嵌套回调链;但我想使用jQuery的when
,then
等功能。但是,在使用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);
});
我做错了什么?我猜它有一些范围问题,因为我可以看到正在执行的第二个get
调用。使用两个不同的args
变量没有帮助,因为传递给done函数的参数仍然是第一个get
请求。
答案 0 :(得分:29)
作为更新:
使用现代jquery(1.8+),时不需要初步,因为 get 会返回延迟承诺。
此外,不推荐使用 pipe 。请改用然后。只需确保返回新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);
});
答案 1 :(得分:12)
所有三个回调(两个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);
});
答案 2 :(得分:1)
这是一个非常简单且高效的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插件-------------------
$。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'); } }
}
答案 3 :(得分:1)
目前投票率最高的答案给出的答案是不对的。
当你有函数a,b,c时,每个函数返回一个$ .Deferred()对象,并将函数链接如下:
a().then(b).then(c)
一旦从a返回的承诺得到解决,b和c都将运行。由于then()函数都与a的承诺相关联,因此与其他Jquery链接类似,例如:
$('#id').html("<div>hello</div>").css({display:"block"})
在从$(&#39;#id&#39;)返回的对象上调用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(),您将看到差异。
答案 4 :(得分:0)
<script type="text/javascript">
var promise1 = function () {
return new
$.Deferred(function (def) {
setTimeout(function () {
console.log("1");
def.resolve();
}, 3000);
}).promise();
};
var promise2 = function () {
return new
$.Deferred(function (def) {
setTimeout(function () {
console.log("2");
def.resolve();
}, 2000);
}).promise();
};
var promise3 = function () {
return new
$.Deferred(function (def) {
setTimeout(function () {
console.log("3");
def.resolve();
}, 1000);
}).promise();
};
var firstCall = function () {
console.log("firstCall");
$.when(promise1())
.then(function () { secondCall(); });
};
var secondCall = function () {
console.log("secondCall")
$.when(promise2()).then(function () { thirdCall(); });
};
var thirdCall = function () {
console.log("thirdCall")
$.when(promise3()).then(function () { console.log("done"); });
};
$(document).ready(function () {
firstCall();
});
</script>
答案 5 :(得分:0)
我想我会把这个小小的练习留给那些可能觉得有用的人,我们建立一系列请求,当它们完成后,我们可以发出一个回调函数:
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)
});
答案 6 :(得分:-2)
我的方法是应用回调函数:
A(function(){
B(function(){
C()})});
其中A,B可写为
function A(callback)
$.ajax{
...
success: function(result){
...
if (callback) callback();
}
}