RxJS - emit only if other does not emit during delay

我怕爱的太早我们不能终老 提交于 2020-05-29 04:53:08

问题


Suppose I have two observables. Every time the first one emits, I want to wait 2 seconds to see whether during that period the other observable emits something. If yes, do not emit anything. If no, emit.

Example:

const start$ = this.events.pipe(
  delay(1000),
  takeUntil(theSecondObservable) // WHAT SHOULD BE HERE?
).subscribe((value) => {
  console.log(value);
});

回答1:


This solution does not complete when the end$ observable emits and uses RxJS 6 syntax.

const start$ = this.router.events.pipe(map(() => true));
const end$ = this.router.events.pipe(map(() => false));

merge(start$, end$)
  .pipe(debounceTime(2000), filter(value => value))
  .subscribe(value => console.log(value));

If you're filtering router events you may not need two observables.

this.router.events
  .pipe(debounceTime(2000), filter(event => event instanceof NavigationEnd))
  .subscribe(value => console.log(value));



回答2:


Use the race operator.

const start$ = race(this.events.pipe(delay(1000)), theSecondObservable).subscribe(value => /** ... */);

Once one of the observables emits an object, the other observable will be ignored and only values emitted by the 'winner' will be passed on to the subscriber. In your subscription function, you can perform some logic to figure out which observable your value came from.




回答3:


Are you interesting in limiting the emitions from the 1st observer or just in the end result?

You can use a race...

let r = race(observer1.pipe(delay(2000)), observer2)
 // r will emmit from observer1 only if observer2 didnt emmit, else it will emmit from observer2



回答4:


I was able to solve it with the help of the answers above. However, they did not completely answer my question and there might be a better way. My solution:

const end$ = this.router.events.pipe(
  map(() => false),
);
const start$ = this.router.events.pipe(
  map(() => true),
);

merge(
  end$,
  start$.pipe(
    switchMap(() => {
      return race(end$, of(true).pipe(delay(2000)));
    }),
    filter((value) => value === true) // this really works only with booleans, not sure how I'd do it with more 
                                                            // complex objects
  )
).subscribe((value) => {
  console.log(value);
});


来源:https://stackoverflow.com/questions/53906200/rxjs-emit-only-if-other-does-not-emit-during-delay

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