【问题标题】:RxJS Observable That waits on Observable等待 Observable 的 RxJS Observable
【发布时间】:2016-01-06 07:40:00
【问题描述】:

所以我有一个可观察的,它发出一个 HTTP 帖子以从服务器获取访问令牌。我有另一个执行对同一服务器的获取,但需要从第一个存在的访问令牌。所以我希望能够在两个不同的地方同时订阅两个 observable,但是 GET observable 当然必须等待 POST observable。如何让 observable 等待另一个 Observables 订阅完成?

【问题讨论】:

    标签: javascript angular rxjs reactive-extensions-js


    【解决方案1】:

    不确定我是否理解正确,但这里有一个选项。假设 postHttp$ 是您可观察到的访问令牌获取,而 getFromServer$ 是执行获取服务器的那个,并假设这些序列只有一个值(即类似承诺):

    • postHttp$.flatMap(function (authToken){return $.ajax(...)}) 将等待 postHttp 有一个值来产生一个承诺,该承诺将被压平到它的解析值。即the GET observable (...) wait on the POST observable. 要检索该值,您可以订阅 observable,或继续将其他运算符链接到它。
      • flatMap 接受 Promise 作为其选择器函数参数的返回值,因此这里无需转换为 Rx.Observable

    这是你想要的吗?

    【讨论】:

      【解决方案2】:

      我想出了一个解决方案,所以我想我会继续发布我自己的答案。如果有人知道更有效的做事方式,肯定会发布答案,我会接受!

      this.getObservable = Rx.Observable.create(function(observer){
        this.postObservable.subscribe(null, null, function onComplete(){
          var ajaxObservable = Rx.Observable.fromPromise($.ajax({
            url: this.apiPath,
            method: 'GET',
            beforeSend: function (xhr) {
              // this.authToken is created by the postObservable, so we have to subscribe to the oncomplete of that in order to use it.  
              xhr.setRequestHeader('Authorization', this.authToken); 
            }.bind(this)
          }).promise());
          ajaxObservable.subscribe(
            function onNext(data){
              observer.next(data);
            }, 
            function onError(error){
              observer.error(error);
            }, 
            function onComplete(){
              observer.complete();
            }
          );
        }.bind(this));
      }.bind(this));
      

      在这段代码中,getObservable 订阅了 postObservable,并且只有在完成后才会进行自己的 Ajax 调用。这很有用,因为它让我的页面可以立即订阅他们想要的任何 GET observable,而不必担心首先订阅 postObservable,然后在准备好后订阅下一个 observable 的回调地狱。对于单个页面,post 请求是完全隐藏的,他们只是订阅了 get 请求。

      请注意,如果使用箭头函数,这段代码可能会更简洁,但我正在努力与一些较旧的浏览器保持兼容。

      【讨论】:

      • 重要的是它适合你。然而: 1. 如果你必须链接一个比这个更长的 observables 序列,它不会是回调地狱,但无论如何它都会是地狱, 2. 这些机制(操作序列)已经在 Rx 操作符中实现,最好的方法是重用和组合现有的代码,这些代码已经过广泛的测试。 3.一般来说,最好是函数式编程,即尽可能使用纯函数(无副作用),这样可以简化你的推理和测试(我这里理解postObservable不知怎么修改authToken)跨度>
      • 你真的只是在做this.postObservable.flatMap(function (authToken){return $.ajax(...)})。然后您可以订阅它以处理来自 ajax 调用的数据。我将更新我的答案以反映新信息。我建议你阅读这篇文章以进一步了解 Rxjs:gist.github.com/staltz/868e7e9bc2a7b8c1f754
      • @user3743222 很有趣。您认为您可以更新您的答案以反映此评论吗?如果你能用我上面给出的变量来表达,我很乐意接受你的回答。
      猜你喜欢
      • 1970-01-01
      • 2021-08-28
      • 2021-11-16
      • 1970-01-01
      • 2021-12-03
      • 2017-09-04
      • 2021-06-30
      • 1970-01-01
      • 2021-11-04
      相关资源
      最近更新 更多