我有以下JS方法:
var foo = function() {
var dfd = $.Deferred();
console.log('foo');
dfd.resolve();
return dfd.promise();
};
var ajaxCall1 = function () {
var dfd = $.Deferred();
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
url: 'xxxxxxx',
data: { },
success: function(response) {
dfd.resolve();
}
});
return dfd.promise();
};
var ajaxCall2 = function () {
var dfd = $.Deferred();
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
url: 'xxxxxxx',
data: {},
success: function (response) {
dfd.resolve();
}
});
return dfd.promise();
};
var ajaxCall3 = function () {
var dfd = $.Deferred();
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
url: 'xxxxxxx',
data: {},
success: function (response) {
dfd.resolve();
}
});
return dfd.promise();
};
我通过这段代码打电话给他们:
foo().done(function () {
return ajaxCall1();
}).done(function () {
return ajaxCall2();
}).done(function () {
return ajaxCall3();
});
问题是在ajaxcall1成功发生之前调用了ajaxCall2。你能帮我解决这个问题吗?当前一个成功发生时,我需要逐个进行ajax调用。
答案 0 :(得分:2)
使用$ .when
var deferredObject = $.ajax({});
$.when(deferredObject)
.then(function(){
var deferredobject2 = $.ajax({});
$.when(deferredobject2)
.then(function(){ alert('after 2nd ajax call');});
});
答案 1 :(得分:1)
首先,您可以直接返回$ .ajax调用的结果,因为它们已经是promise(不需要中间Deferred):
var ajaxCall1 = function () {
return $.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
url: 'xxxxxxx',
data: { }
});
};
var ajaxCall2 = function () {
return $.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
url: 'xxxxxxx',
data: {}
});
};
var ajaxCall3 = function () {
return $.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
url: 'xxxxxxx',
data: {}
});
};
其次,您想要使用.pipe()来有效地链接呼叫:
foo().pipe(function () {
return ajaxCall1();
}).pipe(function () {
return ajaxCall2();
}).pipe(function () {
return ajaxCall3();
}).done(function() {
// call1, call2 and call3 done in sequence
}).fail(function() {
// one of the ajax requests failed
});
答案 2 :(得分:0)
简化。
function foo() {
var dfd = $.Deferred();
console.log('foo');
dfd.resolve();
return dfd.promise();
}
function ajaxCall1() {
return $.ajax({
type: 'POST',
dataType: 'json',
url: 'xxxxxxx',
data: { },
success: function(response) {
console.log('ajaxCall1 success');
}
});
return dfd.promise();
}
// and so on for ajaxCall2 and ajaxCall3
增强。
foo().done(function () {
ajaxCall1().done(function () {
ajaxCall2().done(function () {
ajaxCall3();
});
});
});
http://jsfiddle.net/mattball/LxjDS/
进一步阅读:
答案 3 :(得分:0)
与其他答案相同,只是使用Frame.js
简化回调var responses = [];
for(var i=0; i<1000; i++){
Frame(function(callback){
$.ajax('myserver.api', {
data:i,
type:'post',
complete:function(response) {
responses.push(response);
callback();
}
});
});
}
Frame.start();
通常情况下,使用这样的AJAX请求关闭浏览器会导致浏览器挂起,响应变量将按接收顺序返回,而不是发送给它们的原始顺序。在这里添加框架到混合把这一切排除在外。
或者你可以用它来平掉回调:
Frame(function(next){
foo().done(next);
});
Frame(function(next){
ajaxCall1().done(next);
});
Frame(function(next){
ajaxCall2().done(next);
});
Frame(function(next){
ajaxCall3().done(next);
});
Frame(function(next){
//do more stuff
next();
});
Frame.start();
答案 4 :(得分:0)
我在使用SharePoint网络服务方面遇到了类似的问题 - 在您能够继续工作之前,您经常需要从多个来源提取数据。
为了解决这个问题,我将这种功能嵌入到我的AJAX抽象库中。您可以轻松定义一个请求,该请求将在完成时触发一组处理程序。但是,每个请求都可以使用多个http调用进行定义。这是组件:
这个非常简单的示例创建了一个带有三个调用的请求,然后将这些信息按照调用顺序传递给单个处理程序:
// The handler function
function AddUp(Nums) { alert(Nums[1] + Nums[2] + Nums[3]) };
// Create the pool
myPool = DP_AJAX.createPool();
// Create the request
myRequest = DP_AJAX.createRequest(AddUp);
// Add the calls to the request
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [5,10]);
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [4,6]);
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [7,13]);
// Add the request to the pool
myPool.addRequest(myRequest);
请注意,与许多其他解决方案不同,此方法不会强制进行调用的单线程 - 每个调用仍然会像环境允许的那样快速运行,但只有在完成所有调用时才会调用处理程序。该组件还支持用户定义的请求数,因此您可以根据需要轻松强制执行单线程。它还支持设置超时值和重试尝试,如果您的服务有点冒险。
我发现这种工作非常有用(并且非常简单易懂)。