【问题标题】:Converting Angular2 Http response to ConnectableObservable将 Angular2 Http 响应转换为 ConnectableObservable
【发布时间】:2016-04-13 04:32:18
【问题描述】:

我必须承认我正在使用 Angular2 迈出第一步,我在这里遇到了一个问题,我在理解上有些问题。我正在使用 angular2@2.0.0-beta.0,它依赖于 rxjs@5.0.0-beta.0。

我的意图是发出一个 HTTP 请求(对一个 REST 服务),并允许将响应发送给返回的 observable 的多个订阅者。如果我正确理解文档,我可以使用 publish() 函数来转换例如返回的 Observable http.post 函数到 ConnectableObservable,通过多次调用 ConnectableObservable.subcribe(...) 注册多个订阅者,然后调用 ConnectableObservable.connect() 来实际执行 HTTP 请求,例如像这样:

var obs: Observable<Response> = this.http.post(...);
var cobs: ConnectableObservable<Response> = obs.publish();
cobs.subscribe(sub1);
cobs.subscribe(sub2);
cobs.connect();

至少我的 IDE 接缝同意这一点并且没有显示任何警告。运行代码,我确实收到以下错误:

例外:评估“点击”时出错
原始异常:TypeError:obs.publish 不是函数

如果我在调试器中检查obs 对象,实际上只有极小的documented functions 子集可用。如果我查看implementation of the Observable 类,则确实只实现了一些记录的功能。大多数函数,其中publish函数,只是声明为函数签名,没有任何实际实现。

我是在做一些明显错误的事情,还是完全误解了如何使用 RxJS 可观察对象?

如果重要的话,我正在使用 gulp 构建,使用 npm 来解析和下载依赖项,并从我的 node_modules 目录中包含 rxjs/bundles/Rx.js。

【问题讨论】:

    标签: angular observable rxjs


    【解决方案1】:

    事实上,我认为没有必要使用ConnectableObservable。这是我所做的测试,当收到响应时,两个订阅者都会被调用:

    var observable =
      this.http.get('https://angular2.apispark.net/v1/companies/')
               .map(res => res.json());
    
    observable.subscribe(
      data => console.log('subscribe #1'));
    observable.subscribe(
      data => console.log('subscribe #2'));
    

    编辑

    我认为share 运算符可以满足您的需求:

    var observable =
      this.http.get('https://angular2.apispark.net/v1/companies/')
               .map(res => res.json()).share();
    
    observable.subscribe(
      data => console.log('subscribe #1'));
    observable.subscribe(
      data => console.log('subscribe #2'));
    

    它允许创建一个可连接的 observable(share 方法返回一个 hot observable)。在这种情况下,只执行一个 HTTP 请求……

    这个问题可能对你有帮助:Hot and shared Observable from an EventEmitter

    编辑1

    在 cmets 中进行了一些讨论之后,问题似乎是关于为什么会发生以下错误:TypeError: obs.share is not a function 以及为什么 post 函数返回的 observable 中几乎所有记录的函数都不可用。

    因此解决方案是显式导入 RxJS 运算符,以使其在运行时可用。

    有两种解决方案。按运算符导入:

    import 'rxjs/add/operator/map'
    

    或者更一般地说,如果你想拥有所有可观察的操作符方法:

    import 'rxjs/Rx';
    

    希望对你有帮助, 蒂埃里

    【讨论】:

    • 这是我的第一次尝试,但如果您看到与我相同的行为,使用该代码,实际的 HTTP 请求会执行两次 - 每个订阅者一次。这不是我想要的。
    • share 运算符似乎就是您要寻找的 ;-) 使用它只执行一个 HTTP 请求...
    • 我不确定share 运算符是否是我正在寻找的,但是共享功能也没有实现:“TypeError: obs.share is not a function” 我的问题是还有“为什么 post 函数返回的 observable 中几乎所有记录的函数都不可用?”。
    • 真的。我没有你的错误(“TypeError:obs.share 不是函数”)......我所有的观察者都收到了数据。
    • 让我对共享功能感到担忧的是,从文档中我不清楚实际执行 HTTP 请求的时间。最有可能的是,HTTP 请求是在注册第一个订阅者时启动的。如果在 HTTP 请求完成后添加了后来的订阅者,则从文档中不清楚这些订阅者是否被调用。但重复我自己:我的问题并不是关于发布和共享之间的详细区别,而是为什么几乎所有的 Observable 函数都在运行时对象中丢失。
    猜你喜欢
    • 2016-07-01
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 2022-01-22
    • 2018-01-31
    • 1970-01-01
    相关资源
    最近更新 更多