我有 3 个进程需要 ajax 来完成。但它是异步的,它无法完成我想做的事情..
让我们说:
function a(param1, param2) {
$.post(..., function(result){
if(result){
b();
} else {
console.log("failed a");
}
})
}
function b() {
$.post(..., function(result){
if(result){
c();
} else {
console.log("failed b");
}
})
}
function c() {
$.post(..., function(result){
if(result){
console.log("successful");
} else {
console.log("failed b");
}
})
}
我希望它像这样执行
a
b
c
如您所见,该代码将完美运行。 但如果使用循环。
var data = [{param1 : 1235, param2: 3214}, {param1 : 5432, param2: 9876}];
$.each(data, function(k,v){
a(v.param1, v.param2)
});
它不会按预期工作,只会做:
a
a
b
b
c
c
代替
a
b
c
a
b
c
最佳答案
这种东西有很多种写法。
一种灵活的方法是将“ Action ”与“序列”分开,允许:
- 函数 a、b、c 启动异步 (ajax) 操作,不知道它们将如何排序
- a、b、c 可根据需要重复使用,作为一个或多个序列的一部分或单独使用。
这是一种编码这种方法的方法,使用 .then()
专用于链接逻辑:
function a() {
return $.post(...).then(function(result) {
if(result)
return result;//continue on "success" path.
else
return $.Deferred().reject('a').promise();//convert success to failure.
}, function() {
return 'a';//continue on failure path.
});
}
function b() {
return $.post(...).then(function(result) {
if(result)
return result;//continue on "success" path.
else
return $.Deferred().reject('b').promise();//convert success to failure.
}, function() {
return 'b';//continue on failure path.
});
}
function c() {
return $.post(...).then(function(result) {
if(result)
return result;//continue on "success" path.
else
return $.Deferred().reject('c').promise();//convert success to failure.
}, function() {
return 'c';//continue on failure path.
});
}
a().then(b).then(c).then(function() {
console.log("successful");
}, function(id) {
console.log("failed: " + id);
});
或者,如果您想要从一个循环中调用单个异步函数 a
,那么代码可以是这样的:
function a(obj) {
return $.post(...).then(function(result) {
if(result)
return result;//continue on "success" path.
else
return $.Deferred().reject(obj.id).promise();//convert success to failure.
}, function() {
return obj.id;//continue on failure path.
});
}
var data = [{id:'A', param1:1235, param2:3214}, {id:'B', param1:5432, param2:9876}];
//Note how IDs are included so these data objects can be identified later in failure cases.
var dfrd = $.Deferred();//starter Deferred for later resolution.
var p = dfrd.promise();//A promise derived from the starter Deferred, forming the basis of a .then() chain.
//Build a .then() chain by assignment
$.each(data, function(i, obj) {
p = p.then( function() {
return a(obj);
});//By not including a fail handler here, failures will pass straight through to be handled by the terminal .then()'s fail handler.
});
//Chain a terminal .then(), with success and fail handlers.
p.then(function() {
console.log("successful");
}, function(id) {
console.log("failed: " + id);
});
dfrd.resolve();//Resolve the starter Deferred to get things started.
关于javascript - 链接ajax并按顺序执行。 Jquery 延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16384841/