过滤掉observableB,如果observableA在1秒之前被触发。

huangapple go评论54阅读模式
英文:

filter out observableB if observalbeA get triggered 1s before

问题

我有两个可观察对象,observableA和observableB。

这两个可观察对象可以通过以下三种情况触发:

  1. 仅observableA被触发。
  2. 仅observableB被触发。
  3. 在observableA被触发后,经过1秒延迟后observableB也被触发。

如何处理这两个可观察对象,以确保回调函数不会执行两次?

期望的结果是:回调函数不会执行两次。

英文:

Let's say I have two observables, observableA and observableB.

There are 3 cases for how these two observables can be triggered:

  1. Only observableA gets triggered.
  2. Only observableB gets triggered.
  3. ObservableA gets triggered first, followed by observableB after a 1-second delay.

How can I handle these two observables so that the callback function won't execute twice?

expecting: the callback function won't execute twice

答案1

得分: 1

以下是您的翻译:

这是一个示例,一旦第一个可观察对象被触发,延迟1秒,switchMap 触发第二个可观察对象。

import { of } from 'rxjs';
import { delay, switchMap } from 'rxjs/operators';

const firstObservable = of('Hello');
const secondObservable = of('World');

firstObservable.pipe(
  delay(1000),
  switchMap(() => secondObservable)
).subscribe(result => console.log(result));
英文:

Here is the example for you, once the first observable is triggered, delay 1s and switchmap triggers the second once.

import { of } from 'rxjs';
import { delay, switchMap } from 'rxjs/operators';

const firstObservable = of('Hello');
const secondObservable = of('World');

firstObservable.pipe(
  delay(1000),
  switchMap(() => secondObservable)
).subscribe(result => console.log(result));

答案2

得分: 1

以下是您要翻译的部分:

所以没有说的是,等待看看B是否会在A之后触发是可以的。解决这个问题的唯一方法是在A触发后等待X秒,然后触发以继续A,或者收到B并使用该逻辑。bufferTime可以用作此用途。首先,我们合并A和B,然后缓冲这两个可观察对象。

import { interval, bufferTime, merge, map, switchMap, timer } from 'rxjs';

const obsA = interval(1000)
             .pipe( switchMap( (i) => timer( Math.random() * 1000 ) ) )
             .pipe( map( (x) => `A`) )
const obsB = interval(1000)
             .pipe( switchMap( (i) => timer( Math.random() * 1000 ) ) )
             .pipe( map((y) => `B`))

merge( 
  obsA, 
  obsB 
).pipe( bufferTime(1000) )
.subscribe(x => {
  if( x.length === 0 ) return;
  if( x.every( (item) => item.startsWith("A") ) ) {
    console.log("Only A", x);
  } else if( x.findIndex( (item) => item.startsWith("B") ) === 0 ) {
    console.log("Only B", x);
  } else {
    console.log("A followed by B", x);
  }
})
英文:

So what's not said is that it's ok to wait to see if B is going to trigger after an A. The only way to solve this is have a window in which after A triggers you wait X seconds then trigger to continue with A, or you receive a B and go with that logic. bufferTime can serve as this. First we merge A and B together then we buffer those 2 observables up.

import { interval, bufferTime, merge, map, switchMap, timer } from 'rxjs';

const obsA = interval(1000)
             .pipe( switchMap( (i) => timer( Math.random() * 1000 ) ) )
             .pipe( map( (x) => `A`) )
const obsB = interval(1000)
             .pipe( switchMap( (i) => timer( Math.random() * 1000 ) ) )
             .pipe( map((y) => `B`))

merge( 
  obsA, 
  obsB 
).pipe( bufferTime(1000) )
.subscribe(x => {
  if( x.length === 0 ) return;
  if( x.every( (item) => item.startsWith("A") ) ) {
    console.log("Only A", x);
  } else if( x.findIndex( (item) => item.startsWith("B") ) === 0 ) {
    console.log("Only B", x);
  } else {
    console.log("A followed by B", x);
  }
})

You have to handle the case where neither A nor B fire which will be an empty array, and just ignore it.

huangapple
  • 本文由 发表于 2023年6月13日 10:03:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76461289.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定