美文网首页
RxJS —— takeUntil

RxJS —— takeUntil

作者: 芝麻香油 | 来源:发表于2019-11-22 16:24 被阅读0次

    关于RxJS开篇是takeUntil,主要源于最近刚修复了一个神奇的bug。遂以takeUntil做为开篇。

    看到bug是不是瞬间就激动、兴奋了。下面且看引起这个bug的代码:

    // ...
    this.stream$
      .pipe(
        takeUntil(this.compelete$),
        switchMap(id => 
          combineLatest(
            this.store.pipe(select(getAuth, { id, name: 'create' })),
            this.store.pipe(select(getAuth, { id, name: 'edit' })),
            this.service.getWhiteList()
          )
        ),
      )
      .subscribe(([res1,  res2, res3]) => {
         // ...
       });
    // ...
    

    上面这段代码,主体还是比较容易理解的,监听stream$变化,获取 createedit权限,以及白名单,然后 do something。这个时候 bug 就出现了,表象比较简单就是:白名单设置的权限有问题。

    通过各种 debug,终于发现问题,正常使用时,断点会进入上述代码的subscribe,可是其他异常情况依然进入了上述代码的subscribe

    自我检查:takeUntil 写了,destroy 写了,destroy 里 this.complete$.complete() 也写了。

    那么问题出在哪里了呢?

    原来就出在了 takeUntil 这里,takeUntil写在switchMap前面,那么takeUntil虽然结束了,但是switchMap这个流依然没被关闭。于是乎,讲takeUntil放在switchMap后面,尝试之后问题确实解决了。

    this.complete$ 结束时,由takeUntil操作符返回的 observable 就算完成了,其订阅也会被自动取消。
    然而,由于 stream$的订阅者所订阅的 observable 并非由 takeUntil返回,而是由 switchMap返回,所以当takeUntil的observable 完成时,stream$ 的订阅是不会被自动取消的。
    switchMap的所有 observable 全部完成之前,stream$ 的订阅者都将始终保持订阅。所以,除非 combineLatest率先完成,否则这个订阅将不会结束

    是不是所有的takeUntil都应该放在最后呢?

    当然并不是所有的takeUntil都应该放在最后。

    同时,项目上已经大量使用 rxjs,之前没有align过takeUntil应该放哪,在项目全局搜索会发现这种潜在的bug还有很多,于是乎发现了 rxjs-lint-rules 其中rxjs-no-unsafe-takeuntil,可以帮助检测出所有不规范的,然后逐一修复。

    相关文章

      网友评论

          本文标题:RxJS —— takeUntil

          本文链接:https://www.haomeiwen.com/subject/gfkqwctx.html