Deferred Promise - 运行 每个函数完成后一个一个函数
Deferred Promise - Run Functions One by One after each completes
我有 3 个函数可以对后端系统进行 aync 调用: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
(大概还有其他人)需要 return 一个 promise/Deferred 所以你知道什么时候完成.由于它使用 _checkInstanceStatus
,其中 return 是一个 Deferred,因此它可以通过使用 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
});
}
注意它是如何 returns 调用 then
的结果的,这是调用 then
创建的承诺。该承诺将根据您 return 来自 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。
旁注:我会切换到使用本机 Promises(必要时使用 polyfill 来支持旧浏览器),而不是使用 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();
}
});
});
});
}
用法相同(因为我在第一个例子中使用了已添加到 Deferred 的 Promise API)。
你的函数很难看懂。所以我用 3 种不同的方式定义了 3 个新函数,这样你就可以更容易地理解 jquery deferred。
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 link: https://jsfiddle.net/zmjLaznn/
我有 3 个函数可以对后端系统进行 aync 调用: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
(大概还有其他人)需要 return 一个 promise/Deferred 所以你知道什么时候完成.由于它使用_checkInstanceStatus
,其中 return 是一个 Deferred,因此它可以通过使用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
});
}
注意它是如何 returns 调用 then
的结果的,这是调用 then
创建的承诺。该承诺将根据您 return 来自 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。
旁注:我会切换到使用本机 Promises(必要时使用 polyfill 来支持旧浏览器),而不是使用 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();
}
});
});
});
}
用法相同(因为我在第一个例子中使用了已添加到 Deferred 的 Promise API)。
你的函数很难看懂。所以我用 3 种不同的方式定义了 3 个新函数,这样你就可以更容易地理解 jquery deferred。
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 link: https://jsfiddle.net/zmjLaznn/