behaviourSubject
从其中向组件B广播数据,其中每次在组件B中的按钮上单击一次都会在组件B中触发一个http请求。组件A:
import { Component, OnInit } from '@angular/core';
import { MessagingService } from '../messaging.service';
@Component({
selector: 'app-comp-a',
templateUrl: './comp-a.component.html',
styleUrls: ['./comp-a.component.css']
})
export class CompAComponent implements OnInit {
public i= 0;
constructor(public message: MessagingService) { }
ngOnInit() {
}
broadcast(){
this.message.broadcast({data:`Broadcasted_${this.i}`});
this.i++
}
}
组件B:
import { Component, OnInit } from '@angular/core';
import { MessagingService } from '../messaging.service';
import { switchMap } from 'rxjs/operators';
import { of } from 'rxjs';
@Component({
selector: 'app-comp-b',
templateUrl: './comp-b.component.html',
styleUrls: ['./comp-b.component.css']
})
export class CompBComponent implements OnInit {
public data;
constructor(public message: MessagingService) {}
ngOnInit() {
this.message.getData().pipe(
switchMap(res => {
/**
* here some service call based on brodcasted data.
*
* Lets say service returns json in format
* {
* data:[{},{}]
* }
*/
return of([res.data]);
})
).subscribe(res => {
/**
* So in actual use case I will get
* {
* data:[{},{}]
* }
* in subscription.
*
* now lets assume sometime I get data as null and i tried to access it as res.data[0].some_property
then it will throw js error Cannot read property '0' of undefined so subscription breaks and doesnt complete and stops. and then after subsequent broadcast from comp A doesnt triggers subscription in comp B.. is it expected behaviour?
*/
// let a = this.data[0] //this is delibrate error to simulate my realtime issue
this.data = res
}, (error) => {
console.log("Error happened" + error)
}, () => {
console.log("the subscription is completed")
})
}
}
服务:
import { Injectable } from '@angular/core';
import { Subject, BehaviorSubject } from 'rxjs';
@Injectable()
export class MessagingService {
/**
* Subject to notify the offer console
*/
private _change_in_year_month = new BehaviorSubject<any>({ data:'old data' });
public change_in_year_month = this._change_in_year_month.asObservable();
constructor() { }
/**
*
* @param data data contains either year or (year and month)
* This method will broadcast data to offer console to execute service call
*/
broadcast(data) {
this._change_in_year_month.next(data);
}
/**
* Method will return observable of Subject which can be subscribed in
* offer console component to execute service call
*/
getData() {
return this.change_in_year_month;
}
}
现在可以说组件B中的订阅中发生某种方式的js错误(可能是无法读取未定义的属性“ 0”),然后我的进一步javascript执行停止,并且不侦听后续广播的值。
这是Rxjs的预期行为吗?我该如何处理在订阅块中发生的js错误。
可以在Stackblitz处模拟问题。 最初单击广播按钮,然后您可以看到正在显示的数据。 现在取消注释第38行以模拟问题,然后单击“广播”。它永远不会监听后续呼叫。
答案 0 :(得分:1)
如果可观察的死亡将其称为错误处理程序,并且它们已关闭,则您无法通过它们发送任何消息,这意味着它们已关闭,包括间隔已死的上游所有内容。
如果我们想生活。
隐藏主要观察者链是解决方案
在switchmap
内捕获
每当触发请求switchmap
创建可观察的ajax,这次使用
catch
。
switchMap()
不在乎内部Observable
是否已完成,只有在外部Observable
已完成时才完成。即使内部Observable
链死亡,外部Observable
链仍然有效,因为尚未为外部Observable
链调用错误处理程序。
示例
switchMap((value)=>this.http.get('url' + value).pipe(catchError(() => {return empty()}))
))