【问题标题】:Create Observable immediately and queue up emits until subscription立即创建 Observable 并排队发射直到订阅
【发布时间】:2017-07-28 06:43:42
【问题描述】:

我有一个消息 Observable 用于在页面上显示通知。我遇到的问题是,在消息组件初始化之前页面加载发生错误意味着 Observable 尚未被订阅,因此当我尝试发出错误时未定义。

export class MessageService {
    public messagesSource: Observable<IMessage>;
    private messagesObserver: any;

    constructor() {
        console.log('MessageService constructor called');
        this.messagesSource = new Observable(observer => {
            console.log('MessageService observer called');
            this.messagesObserver = observer;
        }).share();
    }

    public show = (message: IMessage) => {
        if (this.messagesObserver) {
            this.messagesObserver.next(message);
        } else {
            console.error('this.messagesObserver is not initialised', this.messagesObserver);
        }
    }
}


export class MessagingComponent {
    public messages: IMessage[] = [];

    constructor(private messageService: MessageService) {
        console.log('messaging component constructor');
        this.messageService.messagesSource.subscribe(message => this.setMessage(message));
    }
}

// and within my HttpService:
private errorHandler = (error: Response): Observable<any> => {
    const err: string = error.text() || JSON.stringify(error);
    console.error('App error occurred:', err);
    this.messageService.show({ content: err, level: 'danger'});
    return Observable.from([null]);
}

正常操作日志:

导航到http://localhost:8090/

调用MessageService构造函数

消息组件构造函数

调用MessageService观察者

Angular 正在开发模式下运行。

当解析器出现错误时:

导航到http://localhost:8090/jobs

调用MessageService构造函数

GET http://localhost:7777/api/jobs401(未授权)

发生应用错误:授权失败,不记名令牌无效。

this.messagesObserver 未初始化 undefined

消息组件构造函数

调用MessageService观察者

Angular 正在开发模式下运行。

所以我需要一种方法让new Observable(observer) 立即创建观察者,这样它就不会未定义,并且在组件准备好订阅时不会丢失和发出消息。

【问题讨论】:

标签: javascript angular rxjs observable


【解决方案1】:

你需要创建一个BehaviorSubject

观察者可以订阅主题以接收最后一个(或 initial) 值和所有后续通知。

如果您想缓冲所有响应,也可以使用ReplaySubject

希望这会有所帮助!

【讨论】:

  • BehaviorSubject 自己完成了它,除非我必须用 null 初始化它。
  • 好吧,玩了一会,看看ReplaySubject比较合适。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-24
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多