• 操作符和 Ajax
    • 使用 ajax() 操作符
    • 使用 fetch API

    操作符和 Ajax

    这是 Rx 对象上的 ajax 操作符。

    使用 ajax() 操作符

    index.html

    1. <html>
    2. <body>
    3. <div id="result">
    4. </div>
    5. <script src="https://unpkg.com/@reactivex/rxjs@5.0.1/dist/global/Rx.js"></script>
    6. <script src="app.js"></script>
    7. </body>
    8. </html>

    app.js

    1. let person$ = Rx.Observable
    2. .ajax({
    3. url : 'http://swapi.co/api/people/1',
    4. crossDomain: true,
    5. createXHR: function () {
    6. return new XMLHttpRequest();
    7. }
    8. })
    9. .map(e => e.response);
    10. const subscription = person$
    11. .subscribe(res => {
    12. let element = document.getElementById('result');
    13. element.innerHTML = res.name
    14. console.log(res)
    15. });

    有一点坑的是我们调用 ajax() 操作符的方式,除了 url 属性外我们显示地指定了一堆配置。这样做的原因是 ajax 操作符内部是这样运行的:

    执行 ajaxObservable 中的 XHR 的默认工厂函数,并把 withCredentials 默认设置为 true

    所以我们给定了一个自定义工厂函数而且它可以正常运行。我明白目前这也被看做是一个 issue

    使用 fetch API

    1. const fetchSubscription = Rx.Observable
    2. .from(fetch('http://swapi.co/api/people/1'))
    3. .flatMap((res) => Rx.Observable.from(res.json()) )
    4. .subscribe((fetchRes) => {
    5. console.log('fetch sub', fetchRes);
    6. })

    这里有几件事情值得一提

    • fetch api 是基于 promise 的,然而使用 .from() RxJS 允许我们输入一个 promise 作为参数并将其转换为 Observable 。
    • 请求回来的结果是一个 response 对象,需要将它转换成 JSON 。调用 json() 方法可以完成这项工作,但 json() 返回的也是 Promise 。所以我们需要再次使用 from() 操作符。但在一个 Observable 内再创建一个 Observable 的话会形成嵌套的 Observable,这不是我们想要的,我们要的只是 JSON 。所以我们使用一个叫做 flatMap() 的操作符来修复它。想深入了解 flatMap(),请参加这里

    最终我们得到了预期的 JSON,如果要使用 CORS 跨域的话,还得做一些额外的工作。