概述
你有几个选择。您可以使用回调使使用这些函数的代码如下所示:
getStuff(function(results) {
getMoreStuff(results, doSomethingWithStuff);
});
或者像这样,使用 jQueryDeferred
和Promise
对象:
getStuff().then(getMoreStuff).then(doSomethingWithStuff):
使用回调
两者都有getStuff
并getMoreStuff
接受一个参数,该参数是完成后要调用的回调,例如:
function getStuff(callback) {
// ^------------------------------ callback argument
$.ajax({
...
success: function(results) {
// other functions involving results
callback(results);
// ^------------------------------------ use the callback arg
}
});
}
...同样对于getMoreStuff
.
使用Deferred
和Promise
jQuery 的ajax
功能与其Deferred
和Promise
特性相结合。您可以添加return
到现有功能以使其正常工作,例如:
function getStuff(callback) {
return $.ajax({
...
});
}
(注意:不需要success
回调。)
然后这段代码:
getStuff().then(getMoreStuff).then(doSomethingWithStuff);
做这个:
getStuff
开始其ajax
调用并返回该Promise
调用创建的。
当该ajax
调用完成并解决 promise 时,getMoreStuff
将调用结果ajax
作为其第一个参数。它 开始ajax
调用。
当getMoreStuff
的ajax
调用完成时,使用该调用doSomethingWithStuff
的结果(在 中的那个)调用getMoreStuff
。
重要的是使用then
,而不是done
,以便在每个阶段传递正确的结果。(如果你使用done
,两者getMoreStuff
和 doSomethingWithStuff
都会看到getStuff
'sajax
调用的结果。)
这是使用的完整示例ajax
:
小提琴| 备用小提琴,ajax
每个呼叫需要一秒钟(更容易看到正在发生的事情)
function getStuff() {
display("getStuff starting ajax")
return $.ajax({
url: "/echo/json/",
type: "POST",
data: {json: '{"message": "data from first request"}'},
dataType: "json"
});
}
function getMoreStuff(results) {
display("getMoreStuff got " + results.message + ", starting ajax");
return $.ajax({
url: "/echo/json/",
type: "POST",
data: {json: '{"message": "data from second request"}'},
dataType: "json"
});
}
function doSomethingWithStuff(results) {
display("doSomethingWithStuff got " + results.message);
}
getStuff().then(getMoreStuff).then(doSomethingWithStuff);
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
输出:
getStuff 启动 ajax
getMoreStuff 从第一个请求中获取数据,启动 ajax
doSomethingWithStuff 从第二个请求中获取数据
你不需要使用ajax
来获得这个好处,你可以使用你自己的 Deferred
和Promise
对象,这样你就可以编写这样的链:
one().then(two).then(three);
...对于您可能有异步完成的任何情况。
这是一个非ajax
示例:
小提琴
function one() {
var d = new $.Deferred();
display("one running");
setTimeout(function() {
display("one resolving");
d.resolve("one");
}, 1000);
return d.promise();
}
function two(arg) {
var d = new $.Deferred();
display("Two: Got '" + arg + "'");
setTimeout(function() {
display("two resolving");
d.resolve("two");
}, 500);
return d.promise();
}
function three(arg) {
var d = new $.Deferred();
display("Three: Got '" + arg + "'");
setTimeout(function() {
display("three resolving");
d.resolve("three");
}, 500);
return d.promise();
}
one().then(two).then(three);
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
输出:
一个运行
一解决
二:得到“一个”
两个解决
三:得到“二”
三解决
这两个(ajax
示例和非ajax
示例)可以在必要时组合。例如,如果我们getStuff
从ajax
示例中获取并决定在将数据交给 之前必须对数据进行一些处理getMoreStuff
,我们会像这样进行更改:Fiddle
function getStuff() {
// Create our own Deferred
var d = new $.Deferred();
display("getStuff starting ajax")
$.ajax({
url: "/echo/json/",
type: "POST",
data: {json: '{"message": "data from first request"}', delay: 1},
dataType: "json",
success: function(data) {
// Modify the data
data.message = "MODIFIED " + data.message;
// Resolve with the modified data
d.resolve(data);
}
});
return d;
}
请注意,我们使用它的方式没有改变:
getStuff().then(getMoreStuff).then(doSomethingWithStuff);
改变的一切都在getStuff
.
这是整个“promise”概念的一大优点(这完全不是 jQuery 特有的,但 jQuery 为我们提供了方便的版本来使用),它非常适合解耦事物。