【问题标题】:how to EventSource with Redux Observable如何使用 Redux Observable 获取 EventSource
【发布时间】:2016-12-05 20:58:38
【问题描述】:

问题很简单,如何将 redux-observable 与 EventSource 一起使用?

与 RxJs 类似:

const observable = Observable.create(observer => {
  const eventSource = new EventSource('/model-observable');
  return () => {
    eventSource.close();
  };
});

observable.subscribe({
  next: data => {
    this.zone.run(() => this.someStrings.push(data));
  },
  error: err => console.error('something wrong occurred: ' + err)
});

【问题讨论】:

    标签: javascript redux rxjs eventsource redux-observable


    【解决方案1】:

    这听起来更像是一个关于如何连接到 EventSource 的通用 RxJS 问题。这可以通过多种方式完成。如果您只关心消息(而不是错误/打开):

    import { fromEvent } from 'rxjs/observable/fromEvent';
    
    const fromEventSource = url => {
      return new Observable(observer => {
        const source = new EventSource(url);
        const message$ = fromEvent(source, 'message');
        const subscription = message$.subscribe(observer);
    
        return () => {
          subscription.unsubscribe();
          source.close();
        };
      });
    };
    

    如果您关心打开和/或错误,则需要更多代码来将所有内容集中在一起:

    import { Observable } from 'rxjs/Observable';
    import { Subscriber } from 'rxjs/Subscriber';
    
    const fromEventSource = (url, openObserver) => {
      return new Observable(observer => {
        const open = new Subscriber(openObserver);
        const source = new EventSource(url);
    
        const onOpen = event => {
          open.next(event);
          open.complete();
        };
    
        const onError = event => {
          if (event.readyState === EventSource.CLOSED) {
            observer.complete();
          } else {
            observer.error(event);
          }
        };
    
        const onMessage = event => {
          observer.next(event.data);
        };
    
        source.addEventListener('open', onOpen, false);
        source.addEventListener('error', onError, false);
        source.addEventListener('message', onMessage, false);
    
        return () => {
          source.removeEventListener('open', onOpen, false);
          source.removeEventListener('error', onError, false);
          source.removeEventListener('message', onMessage, false);
          source.close();
        };
      });
    };
    
    fromEventSource('http://some-url.com')
      .subscribe(value => console.log(value));
    

    redux-observable 中的用法是这样的:

    const somethingEpic = action$ =>
      action$.ofType(SOMETHING)
        .mergeMap(() =>
          fromEventSource('http://some-url.com')
            .map(message => ({
              type: MESSAGE,
              payload: message
            }))
            .catch(e => Observable.of({
              type: SOMETHING_ERROR,
              payload: e,
              error: true
            }))
        );
    

    【讨论】:

    • @Casy 没问题!
    • 这个例子提供了丰富的信息。但是,我认为它的语法有点过时了。例如,似乎.catch 应该是.catchError。不确定,因为我还在学习 RxJS 和 redux-observable。我几乎让它工作了,除了它只是接收 1 条消息/事件然后关闭订阅。
    • 是的,这是可管道操作符之前的 RxJS v5
    猜你喜欢
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    相关资源
    最近更新 更多