Delay for every element with RXJS

帅比萌擦擦* 提交于 2020-02-02 12:24:29

问题


I'm using RxViz to simulate different actions that comes every 1 sec. When I try

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

on https://rxviz.com

or on my own with a console.log

it keeps displaying the three number 1, 2, 3 at the same time

There's a post about this same problem, but none of the answer works for me. I'm using Rx last version 6

How can I create an observable with a delay

[EDIT] The array can contains anything like number, string or any object


回答1:


If you want to delay each value (by 1 sec for example), you may do something like the following:

 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));
  }

Here I did not modify the internals of the observable created by you. Instead, I just take your observable and apply appropriate operations to achieve what you seem to be expecting.




回答2:


This one works by modifying a little bit @siva636's answer

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



回答3:


Here, you emit in one observable emission the all array. [1,2,3]. You only delay that one emission by 1000 ms. But the emission is still one.

Even if we emit each value on its own, the delay function will only apply to the first emission. The others will come immediately after:

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

There is no magic in the create constructing function. If we want an emission to come every x time:

We could make an interval that emits those values (taken from 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);
});



回答4:


Here is my solution (very clean)

const fakeData = [1,2,3]

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


来源:https://stackoverflow.com/questions/50886975/delay-for-every-element-with-rxjs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!