【问题标题】:How to convert a Fetch API response to RxJS Observable?如何将 Fetch API 响应转换为 RxJS Observable?
【发布时间】:2017-12-06 05:17:04
【问题描述】:

如何将Fetch API 返回的任何内容转换为RxJS ObservableRxJS.fromPromise 有帮助吗?

【问题讨论】:

  • 如果您正在使用 Angular,您可能需要考虑使用 Angular 的 HTTP 服务;如果不是,您可能需要考虑使用 RxJS 的 AjaxObservable。它们具有可取消的优势;承诺不能取消。
  • 这是一个使用 Observable 的 Angular 应用程序,但这个应用程序在 web worker 中工作。 Angular HTTP 与 web worker 不兼容。我不得不破解它才能工作。它不是仍然使用XMLHttpRequest 与 FetchAPI 相比,它的性能比XMLHttpRequest 更好吗?

标签: rxjs es6-promise fetch-api


【解决方案1】:

看看这个article

var result = Rx.Observable.fromPromise(fetch('http://myserver.com/'));
result.subscribe(x => console.log(x), e => console.error(e));

【讨论】:

    【解决方案2】:

    由于 fetch 调用返回另一个包含响应对象的 Promise,我将创建自己的 observable:

    import { Observable } from 'rxjs';
    
    const data$ = Observable.create(observer => {
      fetch('http://server.com')
        .then(response => response.json()) // or text() or blob() etc.
        .then(data => {
          observer.next(data);
          observer.complete();
        })
        .catch(err => observer.error(err));
    });
    
    data$.subscribe(data => /*do something with data*/);

    【讨论】:

    • 真的不明白为什么这被否决了。我认为这实际上是一个比公认答案更强大的解决方案。 Observable.fromPromise(fetch(..)) 将立即触发请求,而上述将在.subscribe() 之后有效地启动它。
    • 我看不出有什么理由在这里导入地图运算符。
    • Observable.create() 已弃用。相反,使用:const data$ = new Observable(observer => {...})
    • @Dacomis 我在文档中看不到任何关于弃用的内容:rxjs-dev.firebaseapp.com/api/index/class/Observable#create
    • @wawka 由于 TSLint,此弃用错误出现在我的 VSCode 中。
    【解决方案3】:

    存在库rxjs-fetch,但我建议不要使用它,而是写:

    const getData = (url, params) => {
        return fetch(url, params).then(r => {
            return r.ok ? r.text() : Promise.reject(`${r.statusText} ${r.status}`)
        })
    }
    
    const getDataObserver = (url, params) => Rx.Observable.fromPromise(getData())
    

    (在 NodeJS 中你需要node-fetch

    【讨论】:

      【解决方案4】:

      我正在使用 rxjs@6。

      接受 observables 的操作符(如 flatMapswitchMap 等)也可以接受 promise。 很简单,如下。

      somethingObservable.pipe(
          flatMap(() => fetch('http://some.api.com/post/1')),
          subscribe((response) => {
              console.log(response);
          }),
      )
      

      【讨论】:

        【解决方案5】:

        使用 rxjs 6.4,您可以使用 from 运算符

        查看此链接:https://www.learnrxjs.io/operators/creation/from.html

        示例在 TS 中:

        public getModelDetails(): Observable<YourType> {
        
        const apiCall = fetch(`yourURL/modelDetails`)
                           .then(response => response.json())
                           .then(responseJson => {
                                  return responseJson as YourType
                            })
        return from(apiCall)
        

        }

        【讨论】:

          【解决方案6】:

          我正在使用 rxjs 6.5.3。我正在使用下面的示例将 Fetch API 响应转换为 RxJS Observable。

          const { from } = rxjs;
          const { map, switchMap } = rxjs.operators
          
          
          const observable = from(fetch('data/user.json')).pipe(
              switchMap(response => response.json())
          )
          
          observable.subscribe(function(result){
              console.log('result', result);
          });
          

          你也可以使用rxjs的fromFetch。但 fetch API 仍处于试验阶段。

          【讨论】:

            【解决方案7】:

            建议使用 observables 取消获取:

            function fetch$(url:string, options:RequestInit) {
              return new Observable<Response>(subscriber => {
                const controller = new AbortController();
                options.signal = controller.signal;
                fetch(url, options)
                .then(res => {
                  subscriber.next(res);
                  subscriber.complete();
                })
                .catch(er => subscriber.error(er));
                return () => { // <- return the observable teardown function
                  controller.abort();
                }
              })
            }
            

            https://davidwalsh.name/cancel-fetch

            【讨论】:

              猜你喜欢
              • 2021-10-27
              • 2016-07-01
              • 2021-05-24
              • 2023-03-23
              • 1970-01-01
              • 2016-12-25
              • 2018-02-19
              • 2021-04-11
              • 2018-02-22
              相关资源
              最近更新 更多