如何将 Fetch API 响应转换为 RxJS Observable?
Posted
技术标签:
【中文标题】如何将 Fetch API 响应转换为 RxJS Observable?【英文标题】:How to convert a Fetch API response to RxJS Observable? 【发布时间】:2017-12-06 05:17:04 【问题描述】:如何将Fetch API 返回的任何内容转换为RxJS Observable? RxJS.fromPromise 有帮助吗?
【问题讨论】:
如果您正在使用 Angular,您可能需要考虑使用 Angular 的 HTTP 服务;如果不是,您可能需要考虑使用 RxJS 的AjaxObservable
。它们具有可取消的优势;承诺不能取消。
这是一个使用 Observable 的 Angular 应用程序,但这个应用程序在 web worker 中工作。 Angular HTTP 与 web worker 不兼容。我不得不破解它才能工作。它不是仍然使用XMLHttpRequest
与 FetchAPI 相比,它的性能比XMLHttpRequest
更好吗?
【参考方案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 的操作符(如 flatMap
、switchMap
等)也可以接受 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
【讨论】:
以上是关于如何将 Fetch API 响应转换为 RxJS Observable?的主要内容,如果未能解决你的问题,请参考以下文章
试图将 jquery AJAX 转换为 Fetch API,如何设置RequestHeader?
如何使用rxjs map挖掘HttpClient get请求响应?