问题描述
我有3个对后端系统进行aync调用的函数:fnOne,fnTwo,fnThree.我知道我做的不正确,但是找不到正确的方法.
I have 3 functions that make aync calls to backend systems : fnOne, fnTwo, fnThree. I know I am not doing it correctly, but cannot figure out the right way.
我首先尝试在每次完成后称呼他们:
I am starting off by trying to call them one by after each completes:
但是,fnOne内部已经有一个延迟的对象,当该对象解决时,它正在兑现我的诺言.
However, fnOne already has a deferred object inside of it and when that is resolved it is resolving my promise.
$.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);
});
});
},
然后计划是尝试将它们链接起来,以便它们一个接一个地运行,就像这样:
Then the plan is to try and chain them, so they run one by one, like so:
$.when(oController._fnOne())
.then(oController._fnTwo())
.then(oController._fnThree())
.done(function(){
console.log("all complete!");
});
推荐答案
以下几点:
-
如果将单个Deferred传递给
$.when
,则无需使用.
fnOne
(可能还有其他)需要返回一个承诺/延迟,以便您知道它何时完成.由于它使用的是_checkInstanceStatus
并返回Deferred,因此可以使用then
:
fnOne
(and presumably the others) needs to return a promise/Deferred so you know when it completes. Since it's using _checkInstanceStatus
, which returns a Deferred, it can do that by using then
:
所以fnOne
可能看起来像这样:
So fnOne
might look like this:
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
处理程序返回的承诺来解决.
Notice how it returns the result of calling then
, which is a promise created by calling then
. That promise will resolve based on the promise you're returning from the then
handler.
其他功能将遵循相同的模式.
You'd follow the same pattern with the other functions.
要一个接一个地链接它们,您可以这样做:
To chain them one after another, you'd do this:
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
是相同的函数.)
(I'm assuming _fnOne
and fnOne
are the same function.)
我假设jQuery的最新版本在Deferreds中具有Promises支持.
I'm assuming a relatively recent version of jQuery that has Promises support in Deferreds.
侧面说明:我将改用本机Promises(必要时使用polyfill以支持旧的浏览器),而不是使用jQuery的Deferred
,它具有...很好的历史,并且API具有变得笨拙. :-)
Side note: I'd switch to using native Promises (with a polyfill if necessary to support old browsers) rather than using jQuery's Deferred
, which has...well, it has a lot of history and the API has gotten cumbersome. :-)
具有原生承诺:
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();
}
});
});
});
}
用法是相同的(因为我使用了第一个示例中已添加到Deferred的Promise API).
Usage is the same (because I used Promise APIs that have been added to Deferred in the first example).
这篇关于延期承诺-每次完成后一一运行功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!