AngularJS - $q.all() 上的失败恢复 [英] AngularJS - fail resilence on $q.all()
问题描述
我正在尝试填充一些本地数据以解决一系列远程调用.
当每个承诺都得到解决时,我加载数据并继续.
方法 $q.all( [] )
正是这样做的:
$q.all([this.getUserInfo(11).then(函数(r){结果.push(r)}),this.getUserConns().then(函数(r){结果.push(r)}),this.getUserCtxs().then(函数(r){结果.push(r)})]).then(函数(){控制台日志(结果)})
问题是,这段代码没有弹性.
如果这些调用中的任何一个失败,没有人会得到鱼!
将调用包装在 try/catch 语句中,只会导致 $q.all()
完全忽略该条目,即使没有失败(注意 func 中的 console.log)..
$q.all([this.getUserInfo2(11).then(函数(r){结果.push(r)}),功能 () {尝试 {this.getUserGroups().then(函数(r){控制台.log(r)结果.push(r)})}抓住(错误){控制台日志(错误)}},]).then(函数(){控制台日志(结果)})
输出:
<块引用><块引用>[对象]
关于如何包装它以具有弹性的任何提示?<小时>感谢@dtabuenc,我更进了一步.实现错误回调,我可以避免断链,并推送已解决的承诺的值.
然而,一个讨厌的异常仍然显示在控制台上......如果我无法尝试/捕捉异步请求,我该如何摆脱这种情况?
来电者代码
return $q.all([this.getUserInfo(user_id).then(函数(r){结果['personal_details'] = r}),this.getUserConns().然后(功能(r){结果['连接'] = r},功能(错误){控制台日志(错误)})]).then(函数(){返回(结果)})
被调用者代码(注入异常)
getUserConns: function() {返回 __doCall( ws.getUserConnections, {} ).then(函数(r){//非常通用的异常注入抛出新错误if (r && r.data['return_code'] === 0) {返回 r.data['entries']}别的 {console.log('无法检索活动 - 错误:'+r.data['return_code'])返回空值}})},
这会起作用,但也会将错误推送到数组.
function push(r) {结果.push(r);}$q.all([this.getUserInfo(11).then(push).catch(push),this.getUserConns().then(push).catch(push),this.getUserCtxs().then(push).catch(push)]).then(函数(){控制台日志(结果);})
<小时>
您还应该提高对 Promise 的理解,永远应该将 try-catch
与 Promise 结合使用 - 使用 Promise 时,您使用 .catch()
方法(其他所有内容都隐式为 try
).这适用于正常错误和异步错误.
如果你想完全忽略错误:
function push(r) {结果.push(r);}函数 noop() {}$q.all([this.getUserInfo(11).then(push).catch(noop),this.getUserConns().then(push).catch(noop),this.getUserCtxs().then(push).catch(noop)]).then(函数(){控制台日志(结果);})
I'm trying to fill some local data resolving a series of remote calls.
When every promise is resolved, I load the data and proceed.
The method $q.all( [] )
does exactly this:
$q.all([
this.getUserInfo(11)
.then(function (r) {
results.push(r)
}),
this.getUserConns()
.then(function (r) {
results.push(r)
}),
this.getUserCtxs()
.then(function (r) {
results.push(r)
})
])
.then(function () {
console.log(results)
})
Problem is, this code is not resilient.
If any of these call fails, nobody gets the fish!
Wrapping the calls in a try/catch statement, simply causes $q.all()
to entirely ignore the entry, even when not failing (note the console.log in the func)...
$q.all([
this.getUserInfo2(11)
.then(function (r) {
results.push(r)
}),
function () {
try {
this.getUserGroups()
.then(function (r) {
console.log(r)
results.push(r)
})
}
catch (err) {
console.log(err)
}
},
])
.then(function () {
console.log(results)
})
Output:
[Object]
Any hint on how I could wrap this to be resilient?
Thanks to @dtabuenc, I've gone one step further. Implementing the error callback, I can avoid the breaking of the chain, and push the values of the resolved promises.
However, a nasty Exception is still displayed on the console... How can I get rid of that if I cannot try/catch on async requests?
Caller code
return $q.all([
this.getUserInfo(user_id)
.then(function (r) {
results['personal_details'] = r
}),
this.getUserConns()
.then(
function (r) {
results['connections'] = r
},
function(err) {
console.log(err)
})
])
.then(function () {
return (results)
})
Callee code (inject with an exception)
getUserConns: function() {
return __doCall( ws.getUserConnections, {} )
.then( function(r) {
// very generic exception injected
throw new Error
if (r && r.data['return_code'] === 0) {
return r.data['entries']
}
else {
console.log('unable to retrieve the activity - err: '+r.data['return_code'])
return null
}
})
},
This will work but also push the errors to the array.
function push(r) {
results.push(r);
}
$q.all([
this.getUserInfo(11).then(push).catch(push),
this.getUserConns().then(push).catch(push),
this.getUserCtxs().then(push).catch(push)
])
.then(function () {
console.log(results);
})
You should also improve your understanding of promises, you never should use try-catch
with promises - when using promises, you use the .catch()
method (with everything else being implicitly a try
). This works for normal errors as well as asynchronous errors.
If you want to totally ignore the errors:
function push(r) {
results.push(r);
}
function noop() {}
$q.all([
this.getUserInfo(11).then(push).catch(noop),
this.getUserConns().then(push).catch(noop),
this.getUserCtxs().then(push).catch(noop)
])
.then(function () {
console.log(results);
})
这篇关于AngularJS - $q.all() 上的失败恢复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!