【问题标题】:Delay for every element with RXJS使用 RXJS 延迟每个元素
【发布时间】:2018-11-25 23:19:40
【问题描述】:

我正在使用 RxViz 来模拟每 1 秒发生的不同动作。当我尝试时

Rx.Observable.create(obs => {
  obs.next([1, 2, 3]); // or could be ['aaa', 'bbbb', 'ccc']
  obs.complete();
}).delay(1000);

https://rxviz.com

或者我自己使用 console.log

它一直同时显示三个数字1、2、3

有一篇关于同样问题的帖子,但没有一个答案对我有用。我正在使用 Rx 最新版本 6

How can I create an observable with a delay

[编辑] 数组可以包含任何东西,如数字、字符串或任何对象

【问题讨论】:

  • 您想按原样延迟数组中的每个值或整个数组?
  • 我想将每个值延迟 1 秒,每个元素可以是数字、字符串、对象之类的任何东西

标签: rxjs


【解决方案1】:

如果您想延迟每个值(例如延迟 1 秒),您可以执行以下操作:

 Rx.Observable.create(obs => {
      obs.next([1, 2, 3]);
      obs.complete();
    })
      .pipe(
        // make observable to emit each element of the array (not the whole array)
        mergeMap((x: [any]) => from(x)),
        // delay each element by 1 sec
        concatMap(x => of(x).pipe(delay(1000)))
      )
      .subscribe(x => console.log(x));
  }

这里我没有修改你创建的 observable 的内部结构。相反,我只是采用您的 observable 并应用适当的操作来实现您似乎期望的结果。

【讨论】:

  • 如果您认为您的解决方案不错。让我寻找concatMap。一旦事情发生,of 运算符不会获取数组并解构它。 from 运营商可以。之后,您需要应用第二个 concatMap 将数组中的每个值转换为 observable 并应用延迟
  • 我在 rxviz 上试过,它只显示一个十字图标,我不得不将你的代码转换为 rxJs 5: Rx.Observable.create(obs => { obs.next([1, 2, 3 ]); obs.complete(); }) .concatMap(x=>of(x) .delay(1000) )
  • 我也尝试在本地运行它,所有数组一次显示,而不是每秒发出每个值: Observable.create(obs => { obs.next([1, 2, 3]); obs.complete(); }).pipe( concatMap(x=>Observable.of(x)), delay(1000) ) .subscribe(a => console.log(a))
  • @John 请用经过测试的工作代码检查我的更新答案。
  • 很好的解决方案,谢谢!简单有效。在此之前我发现了一些可怕的野兽:)
【解决方案2】:

这个通过稍微修改@siva636的回答来工作

Rx.Observable.create(obs => { 
  obs.next(1); 
  obs.next(2); 
  obs.next(3); 
  obs.complete(); 
}.concatMap(x=>Rx.Observable.of(x) .delay(1000) )

【讨论】:

  • 良好而干净的答案,使用 rxjs 6,您应该记住 .of(x) 之后的 .pipe 运算符
【解决方案3】:

这是我的解决方案(非常干净)

const fakeData = [1,2,3]

loadData$() {
    return from(fakeData).pipe(
      concatMap(item => of(item).pipe(
        delay(1000)
      )),
    );
  }

【讨论】:

    【解决方案4】:

    这是一种基于其他响应的简洁方式。

    from([...Array(10).keys()]).pipe(
        concatMap(x => of(x).pipe(delay(1000)))
    ).subscribe(y => console.log(y))
    

    【讨论】:

      【解决方案5】:

      在这里,您在一个可观察的发射中发射 all 数组。 [1,2,3]。 您只需将该发射延迟 1000 毫秒。但发射仍然是一。

      即使我们单独发射每个值,延迟函数也只会应用于第一个发射。其他人会马上来:

      Rx.Observable.create(obs => {
        var arr = [1, 2, 3];
        arr.forEach(item => obs.next(item));
        obs.complete();
      }).delay(1000);
      

      create 构造函数没有魔法。如果我们希望每x 时间发送一次:

      我们可以创建一个发出这些值的间隔(取自learnrxjs

      import { Observable } from 'rxjs/Observable';
      
      /*
        Increment value every 1s, emit even numbers.
      */
      const evenNumbers = Observable.create(function(observer) {
        let value = 0;
        const interval = setInterval(() => {
          observer.next(value);
          value++;
        }, 1000);
      
        return () => clearInterval(interval);
      });
      

      【讨论】:

      • setInterval 不是我要找的,我的示例中的数组是一个 int 数组,但它可以是字符串或对象之类的任何东西。如果我使用 Observable.create,解决方案可能类似于伪代码: Observable.create(obs => {observer.next('aaaa');observer.delay(1000); // 不起作用 observer.next( 'bbbb');observer.delay(1000);observer.next('cccc');});
      猜你喜欢
      • 2017-05-08
      • 2012-01-07
      • 2018-10-17
      • 1970-01-01
      • 2017-01-05
      • 2019-10-08
      • 2017-01-31
      • 1970-01-01
      相关资源
      最近更新 更多