rxjs - rxjs 运算符 `delay` 的混淆行为

标签 rxjs reactivex rxjs-pipeable-operators

我对 rxjs 运算符 delay 有点困惑。

当我用 from 创建的假 observable 测试它时,我只看到初始延迟:

const { from } = Rx;
const { delay, tap } = RxOperators;

from([1, 2, 3, 4]).pipe(
  tap(console.log),
  delay(1000));

(您可以将此代码片段复制并粘贴到 rxviz 中。)

我在其中放置了一个 tap 以确保 from 实际上将数组项作为单独的值而不是单个数组值发出。

最初的延迟不是我所期望的,但至少 the docs 是这样说的:

[...] this operator time shifts the source Observable by that amount of time expressed in milliseconds. The relative time intervals between the values are preserved.



但是,当我使用从事件创建的 observable 对其进行测试时,我会在每个发出的值之前看到延迟:

const { fromEvent } = Rx;
const { delay } = RxOperators;

fromEvent(document, 'click')
  .pipe(delay(1000))

这里发生了什么?为什么 delay 在这两种情况下表现不同?

最佳答案

delay 所做的就是它所说的:每当它收到一个值时,它会在延迟期间保持该值,然后发出它。它对收到的每个值都做同样的事情。 delay 不会更改流中项目之间的相对时间。

因此,当您执行 from([1,2,3,4]).pipe(delay(1000)) 时,会发生以下情况:

  • 时间 0:from 发出 1
  • 时间 0:delay 看到 1 并启动 timer1
  • 时间 0:from 发出 2
  • 时间 0:delay 看到 2 并启动 timer2
  • ...
  • 时间 1000:timer1 完成并且 delay 发出 1
  • 时间 1000:timer2 完成并且 delay 发出 2
  • ...

  • 因此,因为所有 4 个值都是快速连续发出的,所以您实际上只会看到初始延迟,然后所有 4 个值都向下游发出。实际上,每个值都从最初发出时延迟了 1 秒。

    如果您想“分开”这些项目,使它们至少相隔 1 秒,那么您可以执行以下操作:
    const source = from([1, 2, 3, 4])
    const spread = source.pipe(concatMap(value => of(value).pipe(delay(1000))));
    spread.subscribe(value => console.log(value));
    

    这会将每个单独的值转换为一个可观察的对象,在延迟后发出该值,然后连接这些可观察对象。这意味着在前一个项目的计时器完成之前,每个项目的计时器不会开始计时。

    关于rxjs - rxjs 运算符 `delay` 的混淆行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56939066/

    相关文章:

    angular - 如何使用BehaviorSubject获取所有项目和单个项目?

    angular - 带有搜索输入框和复选框的多过滤 ngFor 列表

    angular - 基于有效载荷而不是效果取消可观察

    ios - 链中 "take"运算符序列有什么区别

    typescript - 订阅推送通知服务后添加管道

    angular - RxJS 运算符执行顺序

    angular - 如何将项目附加到 Observable

    angular - Rxjs - 使用 observables 作为值重新映射对象

    rxjs - ReactiveX/Rx.NET 中 RxJS switchMap 的等效项

    javascript - 如何通过 rxjs 运算符操作从请求中获取的对象?