我知道这个问题看起来很简单,但是网络上关于 Observables 和错误处理的资源并不是很好(或者我可能只是不擅长搜索)。
我有一个 http 请求返回一个 Observable 的 Response,这些 Response 可以包含数据或错误消息。如果它包含数据我想提取它并解析它,如果它包含错误消息我想跳过所有其他运算符(关于解析)并在订阅者中执行错误函数。
我可以做所有这些抛出错误的事情:
http.get(...).
...
.do(res=>{
if(res.error) throw new Error(res.error.message);
return res;
})
它起作用了,它跳过所有运算符并执行错误函数。问题是,错误发生后,订阅者 停止并且不再接受数据。
如果我在错误发生后分析订阅者,我注意到属性 closed 和 isStopped 都设置为 true。我想防止这种情况,我想在错误发生后也让 Observable 保持事件状态。我该怎么做?
谢谢
最佳答案
如之前的回答所述,这是标准行为,由 Rxjs
可观察对象的契约保证。如果你想逃避契约,你可以materialize
你的源代码,在这种情况下,你将处理元消息(称为通知,您期望的三种类型,next
、error
、complete
)。元消息没有契约,这会让您产生错误、手动完成消息或使用 dematerialize
返回正常行为的负担。
一般来说,可观察对象非常适合数据流,而控制流通常很费力(跳跃、循环、条件分支等)。
请参阅此处的通知
文档:http://reactivex.io/rxjs/class/es6/Notification.js~Notification.html .
请参阅此处的materialize
文档:http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-materialize
因此,如果您想在不停止可观察源的情况下处理错误,您可以这样做:
function process(source, success, error) {
return source.materialize()
.map(function(notification){
const value = notification.value; // that is the actual message data
if (notification.kind === 'N') {
// that is a next message, we keep it a next message
return Notification.createNext(success(value));
}
if (notification.kind === 'E') {
// that is a error message, we turned into a next message
return Notification.createNext(error(value));
}
if (notification.kind === 'C') {
// that is a completed message, we keep it a completed message
return Notification.createComplete();
}
})
.dematerialize()
}
然后您可以将此函数与您的源可观察对象一起使用,并将它传递给处理流值的成功和错误函数。如您所见,这里的技术是将错误消息转换为正常消息,然后恢复为正常。
这是我凭空想出来的,未经测试,如果对您有帮助,请随时告诉我最新消息。我在 Rxjs v4 中多次使用了类似的技术,我相信它应该以直接的方式转化为 Rxjs v5。
关于angular - 出错后不要关闭 Observable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42818678/