Jay*_*Jay 11 javascript ajax jquery
我程序中的几乎所有函数都有某种异步调用,但它们都依赖于某些先前函数的结果.因此,我将下一个函数调用硬编码到每个函数中:
function getStuff() {
$.ajax({
...
success: function(results) {
// other functions involving results
getMoreStuff(results);
}
});
}
function getMoreStuff(results) {
$.ajax({
...
success: function(moreResults) {
// other functions involving moreResults
doSomethingWithStuff(moreResults);
}
);
}
Run Code Online (Sandbox Code Playgroud)
等等.它是一个大型链,每个函数调用下一个函数.虽然这在程序中有效,但它使每个函数都无法单独使用.
我对如何避免这个问题有点失落.我无法弄清楚如何使用通用回调函数,因为当我进行函数调用时,它会像这样结束(使用上面的函数):
getStuff(function() {
getMoreStuff(results, doSomethingWithStuff);
};
Run Code Online (Sandbox Code Playgroud)
但是,"结果"还没有定义.
解决方案似乎很明显,我只是对它有点密集.抱歉!
T.J*_*der 11
你有几个选择.您可以使用回调来使用这些函数看起来像这样的代码:
getStuff(function(results) {
getMoreStuff(results, doSomethingWithStuff);
});
Run Code Online (Sandbox Code Playgroud)
或者像这样,使用jQuery Deferred
和Promise
对象:
getStuff().then(getMoreStuff).then(doSomethingWithStuff):
Run Code Online (Sandbox Code Playgroud)
同时拥有getStuff
并getMoreStuff
接受一个参数,这个参数在完成后调用,例如:
function getStuff(callback) {
// ^------------------------------ callback argument
$.ajax({
...
success: function(results) {
// other functions involving results
callback(results);
// ^------------------------------------ use the callback arg
}
});
}
Run Code Online (Sandbox Code Playgroud)
......同样如此getMoreStuff
.
Deferred
和Promise
jQuery的ajax
功能,其集成Deferred
和Promise
功能.您只需添加return
到现有功能即可实现,例如:
function getStuff(callback) {
return $.ajax({
...
});
}
Run Code Online (Sandbox Code Playgroud)
(注意:不需要success
回调.)
然后这段代码:
getStuff().then(getMoreStuff).then(doSomethingWithStuff);
Run Code Online (Sandbox Code Playgroud)
做这个:
getStuff
开始ajax
调用并返回该Promise
调用创建的内容.
当该ajax
调用完成并解析promise时,getMoreStuff
将调用该ajax
调用的结果作为其第一个参数.它开始了 ajax
电话.
当getMoreStuff
的ajax
调用完成,doSomethingWithStuff
被称为具有的结果是调用(一中getMoreStuff
).
使用then
而不是done
为了在每个阶段获得正确的结果是很重要的.(如果你使用done
,都getMoreStuff
和 doSomethingWithStuff
会看到结果getStuff
的ajax
电话.)
这是一个完整的例子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);
}
Run Code Online (Sandbox Code Playgroud)
输出:
getStuff starting ajax getMoreStuff got data from first request, starting ajax doSomethingWithStuff got data from second request
您不需要使用它ajax
来获得这方面的好处,您可以使用自己的 Deferred
和Promise
对象,这可以让您编写如下链:
one().then(two).then(three);
Run Code Online (Sandbox Code Playgroud)
...对于您可能有异步完成的任何情况.
这是一个非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);
}
Run Code Online (Sandbox Code Playgroud)
输出:
one running one resolving Two: Got 'one' two resolving Three: Got 'two' three resolving
必要时可以组合这两个(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;
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们如何使用它并没有改变:
getStuff().then(getMoreStuff).then(doSomethingWithStuff);
Run Code Online (Sandbox Code Playgroud)
所有改变都在内getStuff
.
这是关于整个"承诺"概念的一个伟大的事情(它完全不是jQuery特有的,但jQuery为我们提供了方便的版本),它非常适合解耦.
尝试
function getStuff() {
return $.ajax({
...
success: function(results) {
// other functions involving results
}
});
}
function getMoreStuff(results) {
return $.ajax({
...
success: function(moreResults) {
// other functions involving moreResults
}
);
}
Run Code Online (Sandbox Code Playgroud)
然后
getStufff().done(function(){
getMoreStuff().done(doSomethingWithStuff)
})
Run Code Online (Sandbox Code Playgroud)
等等
归档时间: |
|
查看次数: |
559 次 |
最近记录: |