延期承诺 - 每次完成后逐一运行函数
问题描述:
我有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!");
});
答
几件事:
如果您传递单个Deferred,则不需要使用
$.when
。fnOne
(大概其他)需要回报承诺/递延,让你知道当它完成。由于它的使用_checkInstanceStatus
,它返回一个延迟,它可以做,通过使用then
:
所以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
是相同的功能。)
我假设相对最近版本的jQuery在Deferreds中有Promises支持。
附注:我会切换到使用本地的承诺(以在必要时支持旧的浏览器填充工具),而不是使用jQuery的Deferred
,其中有...好,它有很多的历史和的API变得繁琐。:-)
随着原生承诺:
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)。
答
这很难理解你的功能。所以我已经简化了以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/
恐怕是不太足够的信息,在这个问题给你一个坚实的答案。例如,“fnOne”所做的“打电话”是什么?这是否会返回Promise或Deferred? –
@ T.J.Crowder感谢您的回复,调用是调用数据后端系统的地方,在解决延迟后,调用已成功完成pDeferred.resolve(); – neeko
这个对后端系统的调用是通过'$ .ajax'来实现的吗?再次说明:它是否会返回Promise或Deferred,或者? –