我有3个函数可以对后端系统进行异步调用:fnOne,fnTwo,fnThree。我知道我没有正确地做到这一点,但无法找到正确的方法。
我开始尝试在每次完成后调用它们:
然而,fnOne内部已经有一个延迟对象,当它被解决时,它正在解决我的承诺。
$.when(oController._fnOne()).done(function(){
console.log("fn one complete");
});
功能
_fnOne: function(){
var oController = this;
//when the deferred is done in _checkInstanceStatus, it is resolving the above, rather than the pDeferred in this function resolving the above.
$.when(oController._checkInstanceStatus(oParams)).done(function(oStatusData) {
//does some stuff
return $.Deferred(function() {
var pDeferred = this;
//does a call for data and upon success i will resolve ..
pDeferred.resolve();
});
});
}
其他功能
_checkInstanceStatus: function(oParams){
return $.Deferred(function() {
var pDeffered = this;
//does a call for data and upon success i will resolve...
pDeffered.resolve(data);
});
});
},
然后计划是尝试链接它们,所以它们一个接一个地运行,如下:
$.when(oController._fnOne())
.then(oController._fnTwo())
.then(oController._fnThree())
.done(function(){
console.log("all complete!");
});
答案 0 :(得分:3)
有几件事:
如果您将单个Deferred传递给$.when
,则无需使用fnOne
。
_checkInstanceStatus
(可能是其他人)需要返回承诺/延期,以便您知道何时完成。由于它使用then
,它返回Deferred,因此可以使用fnOne
来执行此操作:
所以fnOne: function() {
var oController = this;
return oController.__checkInstanceStatus(oParams).then(function(oStatusData) {
var pDeferred = $.Deferred();
callAmazon(function() {
if (/*successful*/) {
pDeferred.resolve();
} else {
pDeferred.reject();
}
});
return pDeferred.promise(); // Or just the Deferred if you like, but
// normally you want to share promises, not
// Deferred objects
});
}
可能如下所示:
then
注意如何返回调用then
的结果,这是通过调用then
创建的承诺。该承诺将根据您从oController._fnOne()
.then(oController._fnTwo) // Notice no () on that, we're passing the
.then(oController._fnThree) // function in, not calling it. Same on this line.
.then(function() {
console.log("all complete!");
})
.catch(function(error) {
// Do something about the error
});
处理程序返回的承诺来解决。
您使用与其他功能相同的模式。
要一个接一个地链接它们,你要这样做:
_fnOne
(我假设fnOne
和Deferred
功能相同。)
我假设一个相对较新版本的jQuery,它在Deferreds中支持Promises。
旁注:我转而使用原生Promise(必要时使用polyfill来支持旧浏览器),而不是使用jQuery的fnOne: function() {
var oController = this;
return oController.__checkInstanceStatus(oParams).then(function(oStatusData) {
return new Promise(function(resolve, reject) {
callAmazon(function() {
if (/*successful*/) {
resolve();
} else {
reject();
}
});
});
});
}
,它有......好吧,它有很多历史和API变得繁琐。 : - )
有本地承诺:
{{1}}
用法是相同的(因为我使用了在第一个示例中添加到Deferred的Promise API)。
答案 1 :(得分:2)
理解你的功能非常困难。所以我简单地用3种不同的方式定义3个新的func,这样你就可以更容易理解jquery延迟。
var funcOne = function() {
var defer = $.Deferred();
$.ajax('/echo/json')
.then(function(data) {
console.log('func1', data);
return defer.resolve(data);
});
return defer;
}
var funcTwo = function() {
console.log('begin call func 2');
return $.ajax('/echo/json')
.then(function(data) {
console.log('func2', data);
return $.Deferred().resolve(data);
});
}
var funcThree = $.ajax('/echo/json');
funcOne()
.then(funcTwo)
.then(funcThree)
.then(function(data) {
console.log('finally got func 3 data', data)
});
jsfiddle链接:https://jsfiddle.net/zmjLaznn/