【问题标题】:timeout inside a subscription rxjs订阅 rxjs 中的超时
【发布时间】:2020-02-13 21:15:42
【问题描述】:

我有以下代码

this.someFormGroup.controls['control1'].valueChanges.subscribe(val => {
   if (val) {
      doStuff();
   }
   setTimeout(() => doOtherStuff(), 1000);
});

我想知道是否有另一种方法可以在不使用 setTimeout 的情况下实现这一点,我正在考虑来自 rxjs 的 timer,但我不确定如何将其合并到这里。

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    尽管上述解决方案有效,但管道副作用绝不是您想要的解决方案。 Rx 的一大优势是您始终知道发生了什么何时以及如何。有很多文章介绍了为什么一般不应该使用副作用:

    另外请记住:在没有点击的情况下实施解决方案总是,真的总是可能的,而且大多数时候你可以看到它很容易。

    private readonly valueChanges$: Observable<any> = this.someFormGroup.controls['control1'].valueChanges
    
    private readonly delayedValuechanges$: Observable<any> = this.valueChanges$.pipe(
      delay(1000)
    )
    
    constructor(private readonly someFormGroup: SomeFormGroup) {
      this.valueChanges$.subscribe(this.doStuff);
      this.delayedValueChanges$.subscribe(this.doOtherStuff);
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用tapdelay

      this.someFormGroup.controls['control1'].valueChanges
        .pipe(
          tap(val => {
            if (val) {
              doStuff();
            }
          }),
          delay(1000),
        )
        .subscribe(() => doOtherStuff());
      

      【讨论】:

      • 在 rx 管道中实现副作用是一种不好的做法。我会避免这种解决方案。我提供了两个链接的答案,为什么它不好。你可以找到很多关于干净代码、副作用的文章。如果你想详细了解,我推荐阅读:Clean Code, Robert Martin
      • tap() 操作符的唯一目的是产生副作用,实际上不可能创建没有副作用的 RxJS 链。这就是为什么你有一个特殊的运算符并且你不会在'map()'中产生副作用。这就是为什么 RxJS 核心中的 tap() rxjs.dev/api/operators/tap
      • 一般来说,你可以用 JavaScript 编写糟糕的代码。只有语言或框架支持功能/操作并不意味着它是一个好的实践。 rx 和 clean 编程的目标是将副作用尽可能地移到最后。这总是意味着订阅。如果您在一个更大的项目中工作,具有副作用的管道会导致您的系统以非常耗时的方式进行维护。
      • 好吧,我在这个网站上有 1000 个标有“rxjs”的答案,我不想让你气馁,但你会对 RxJS 感到非常失望,因为盲目地坚持一个规则'不是一开始就为响应式编程创建的(!)将导致您获得绝对可笑的复杂解决方案。您建议的书(我实际上非常了解这本书)还建议使用最多 4 行代码编写方法,并且当有更多方法可以解决一件事时,您应该使用奥卡姆剃刀。所以你可以从中获取任何你想要的东西:)。
      • 首先: rx 中的 1000 个答案通常并不意味着您是对的。我没有说你的代码不起作用。第二:对于没有经验的 rx 程序员,这是一个普遍的坏方法,不应该被建议。仅仅让代码工作并不意味着它是好的。第三:在管道中不使用副作用通常不会导致复杂的解决方案,并且随着时间的推移它将提高您的代码可维护性。第四:如果你在 rx 中有 1000 个答案,很遗憾你提供了这样的解决方案 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多