我正在使用rxjs 5.5.6。
我已创建此代码以显示其行为:
Observable.of(1, 2)
.do(a => {
console.log(a);
let d:string = null;
let r = d.length; // it raises an null exception
})
.catch(() => {
console.log("error catched"); //exception is capture here
return Observable.never();
})
.subscribe();
我期望输出为:
1
error catched
2
error catched
但是,输出为:
1
error catched
这意味着,尽管Observable.never()
方法链上返回了.catch(...)
,订阅还是终止了。
有什么想法吗?
真实案例
this.subs = Observable
.merge(this.$searchQuery, this.$lazyQuery)
.do(() => this.loadingPage())
.map(filter => this.buildURL(user, app, filter))
.switchMap(url => this.service.getItemsFromService(url))
.map(response => this.buildPage(response))
.do(page => this.loadedPage(page))
.catch(() => {
this.loadedPage(pojo.Page.EMPTY);
return Observable.never();
})
.takeUntil(this.$unsubscribe)
.subscribe();
答案 0 :(得分:1)
您将获得输出
1
error catched
因为第一个值在tap
中引发错误,该错误会通过onError
通道传播,从而终止序列。使用catch
时,您会捕获到此错误并继续执行下一个序列(never
),但是第一个序列(of(1,2)
)仍被暂停。因此,1
引发错误后,2
永远不会处理tap
。
在never
中返回catch
后,不会发出任何值,并且Observable永远不会完成。如果在subscribe
内为next
,error
和complete
回调添加日志,您将发现它们从未执行过。
答案 1 :(得分:1)
是的,@ frido的所有解释都是正确的。有了这个答案,我想补充:
如果要捕获任何特定的Observable本身发生的任何错误(例如HTTP请求),则需要在该特定的错误Observable中对其进行处理。
let correct = Observable.of("correct")
let inCorrect = Observable.throw('inCorect')
let obs = [inCorrect, correct];
let handledObs = obs.map(eachObs => {
return eachObs.catch((e) => {
console.log("Individual handler, Good Catch!");
return Observable.of("I am tampered");
})
})
forkJoin(...handledObs)
.do(a => {
console.log(a);
})
.catch(() => {
console.log("error catched");
return Observable.never();
})
.subscribe(data => {
console.log(`data`, data)
},(e) => {
console.log(`error`, e)
});
}
在此处查看示例:https://stackblitz.com/edit/angular-7mmhn7?file=src/app/app.component.ts
编辑
但是,当我查看您的代码时,在我看来您正在尝试记录某些内容,并且返回的数据可能没有length
属性,即使在这种情况下,您也想继续使用流。如果是这样,则可以在try
catch
do()
from([1, 2])
.do(a => {
try {
console.log(a);
let d:string = null;
let r = d.length;
} catch(e) {
console.log(`catched under do`, e)
}
})
.catch(() => {
console.log("error catched");
return Observable.of('catched');
})
.subscribe(data => {
console.log(`data`, data)
},(e) => {
console.log(`error`, e)
});
这里是一个示例:https://stackblitz.com/edit/angular-bcrava?file=src/app/app.component.ts