Angular - RxJS运算符.first()在从Http升级到HttpClient后抛出类型错误

时间:2018-02-01 09:40:21

标签: angular rxjs rxjs5 angular-httpclient

我最近将我的角度应用升级为使用HttpClient而不是Http。在处理了header和params的一些修复程序之后,我的大多数代码都工作了,但是一个特定的请求暗示了我的奇怪行为。

请求有点特殊,因为它是一个轮询请求,当它从服务器获得一个有效负载时会发出声响(它将返回一个204响应,直到它有东西要传递)。

我正在使用一个Observable间隔在特定的时间跨度内每秒轮询一次端点,当我得到一个有效负载时,我使用.first()运算符来处理数据。当我使用旧的Http服务时,这很好用。这是它的外观:

error TS2345: Argument of type '(data: Object) => Object' is not assignable to parameter of type '(value: Object, index: number, source: Observable<Object>) => boolean'. Type 'Object' is not assignable to type 'boolean'.

当我使用不推荐使用的Http服务时,observable可以正常工作,但是当我使用HttpClient服务时,我收到以下错误:

return Observable.interval(this.pollInterval)
  .mergeMap(() => this.http.get(this.apiUrl + '/poll'))
  .do(console.log)
  .first(data => data)
  .map(result => result)
  .timeout(20000)
  .catch(this.errorHandler);

现在这里有点奇怪,我决定尝试通过在.first()运算符之前添加.do(console.log)来调试可观察流,如下所示:

{{1}}

这样做似乎解决了问题,没有更多的类型分配错误,并且想要的功能像以前一样工作。我已经使用了一个我在.do()操作符中调用的虚函数,但我不满意必须这样做才能解决问题,所以我想弄清楚为什么会出现这种行为以及是什么.do()运算符可以解决问题。

期待听到您对此问题的意见。

解决方案 我按照第一个答案的建议使用!!在.first()返回中将数据类型转换为boolean,这消除了类型错误,并删除了使用问题中描述的.do()操作的需要。

1 个答案:

答案 0 :(得分:1)

如果do()解决了问题,那么实际上似乎是do()与RxJS&lt; 5.5。该操作符仅用于副作用,不应以任何方式改变链。所以检查一下RxJS版本,也许这就是问题https://github.com/ReactiveX/RxJS/commit/9a40297

无论如何,first()的回调需要以下类型(http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-first):

function(value: T, index: number, source: Observable<T>): boolean

我认为错误会告诉你究竟出了什么问题。您正在使用first(data => data),因此您不会返回boolean而是Object

如果我了解您要执行的操作,则需要根据对象是否存在将对象转为truefalse

.first(data => !!data)

......或者可能不是蹩脚的解决方案:

.first(Boolean)

另一个问题是你是否需要使用first。它意味着如果源Observable完成并且没有匹配的项目或者它已经完成并且有多个匹配的项目并且我认为在您的情况下没有这些chan发生则发出错误。因此,使用filter(Boolean)可能会更有意义。