【问题标题】:RxJS5 emit array items over time and repeat foreverRxJS5 随着时间的推移发出数组项并永远重复
【发布时间】:2016-12-19 15:02:51
【问题描述】:

我想随着时间的推移发射数组项目(每次发射之间间隔一秒),当所有项目都发射完毕后,一遍又一遍地重复。

我知道该怎么做,但我想知道是否有比..更简洁的东西。

const MY_ARRAY = ['one','two','three'];
const item$ = Rx.Observable.interval(1000).take(MY_ARRAY.length).repeat().map(x => MY_ARRAY[x]);
item$.subscribe(x => console.log(x));

谢谢

输出是..

“一个”

“两个”

“三”

“一个”

“两个”

“三”

编辑:

ATOW,这里的答案总结为..

const ARR = ['one', 'two', 'three'];

// TAKE YOUR PICK THEY ALL DO THE SAME
const item$ = Rx.Observable.interval(1000).map(i => ARR[i % ARR.length]);
// const item$ = Rx.Observable.interval(1000).zip(ARR, (a, x) => x).repeat();
// const item$ = Rx.Observable.interval(1000).zip(ARR).repeat().map(x => x[1]);
// const item$ = Rx.Observable.interval(1000).take(ARR.length).repeat().map(i => ARR[i]);

item$.subscribe((x) => {
  console.log(x);
});

【问题讨论】:

    标签: angular rxjs rxjs5


    【解决方案1】:
    Observable.interval(1000).map(i => MY_ARRAY[i % MY_ARRAY.length])
    

    【讨论】:

    • 接受这个。其他答案也很好,但这是最短的(代码高尔夫获胜者)并且是最易读的。没有充分利用 RXJS 运算符,但有时简单是最好的。
    • 这是一个很好的答案,但我认为它不可读,您团队中的每个其他开发人员都不会立即理解代码的作用。所以不要忘记发表评论:)
    • 我能理解你的意思。就我个人而言,感觉更自然。我想可读性与团队习惯于做事有关。 zipIterable' with the _` 运算符对某些人来说可能更复杂。
    • 我觉得这更易读Observable.interval(1000).map(iteration => MY_ARRAY[iteration % MY_ARRAY.length])
    • 如果数组的长度随时间变化,你会如何修改?例如,如果在第一次迭代中数组有 23 个元素,而在第二次迭代中它有 28 个元素呢?但迭代不应该停止并且是无缝的,从一个项目移动到另一个项目。
    【解决方案2】:

    您可以使用 zip 运算符:

    const interval$ = Rx.Observable.interval(1000);
    const items$ = Rx.Observable.from([1,2,3]);
    
    const itemsOverTime$ = interval$.zip(items$).repeat();
    
    
    itemsOverTime$.subscribe(([time, val]) => {
      console.log(val);
      // 1
      // 2
      // 3
      // 1
      // 2
      // 3
    });
    

    【讨论】:

    • 如果数组的长度随时间变化,你会如何修改?
    【解决方案3】:

    zip 是这里的首选运算符,但使用 Observable.from 会在订阅时转储所有值,并且需要 zip 来保留值的副本。这对于大型阵列并不理想。 zip 的原始 IEnumerable<T> 重载实现为 zipIterable

    const MY_ARRAY = ['one','two','three'];
    Rx.Observable.interval(1000).zipIterable(MY_ARRAY, (_, v) => v).subscribe(v => console.log(v))
    

    【讨论】:

    • zipIterable 不是 RXJS5 中的函数?当您将 zipIterable() 替换为 zip() 时有效。我认为您正在尝试做一些我不够聪明无法理解的事情。谢谢您的回答
    【解决方案4】:

    使用zip 组合来自intervalfrom 的流,这样对于每个间隔时间,都会发出一个值。然后你用repeat 操作符将上面的 observable 管道化,不带参数永远发出值。

    const { interval, from, zip } = require('rxjs');
    const { repeat } = require('rxjs/operators')
    
    const itemsOverTime$ = zip(
        interval(1000),
        from(MY_ARRAY)
    ).pipe(repeat());
    
    itemsOverTime$.subscribe(([time, val]) => {
        console.log(val);
    });
    

    【讨论】:

    • 这里不鼓励仅使用代码的答案。请添加说明,说明您的答案如何解决问题,以及为什么它可能优于已提供的其他答案。
    猜你喜欢
    • 1970-01-01
    • 2013-06-19
    • 2018-09-10
    • 2020-04-21
    • 1970-01-01
    • 2022-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多