【问题标题】:Polling using expand in rxjs gives an unexpected result在 rxjs 中使用 expand 轮询会产生意想不到的结果
【发布时间】:2021-06-27 23:32:21
【问题描述】:

我正在尝试使用 expand 设置轮询器,但行为不是我想要的

https://stackblitz.com/edit/rxjs-finalize-unsubscribe-6xy2yb?file=index.ts

checkExistence 产生一个随机布尔值 - 通过展开,我期望相同 checkExistence 函数的递归延迟调用每 5 秒(在一次初始调用之后)产生随机布尔值。

我还希望停止在 30 秒内启动并停止轮询,并在 5 秒后恢复随机布尔流。任何指针都会有所帮助。

相反,我得到了相同的布尔值被打印出来;同样在 start 被触发后,它会一起产生一批布尔值。

【问题讨论】:

    标签: rxjs rxjs6 rxjs-observables rxjs-pipeable-operators


    【解决方案1】:

    这不是一个真正的问题。

    赋值/函数调用

    一个简化的例子

    等号运算符为变量赋值。函数调用返回值

    function inc(n){
      return n + 1
    }
    
    const result = inc(5)
    console.log(result); // 6 
    

    这里的结果是数值6。不是计算5+1的函数。5+1在这里只发生一次。

    现在考虑这个随机增加数字 1 或 2 的函数

    function bump(n){
      const nu = Math.random();
      return nu < 0.5 ? n + 1 : n + 2 
    }
    
    const result = bump(5);
    console.log(result); // 7
    console.log(result); // 7 
    console.log(result); // 7 
    console.log(result); // 7 
    console.log(result); // 7 
    

    每次打印结果都是一样的。 bump 只被调用了一次,并且只生成了一次随机数。

    function bump(n){
      const nu = Math.random();
      return nu < 0.5 ? n + 1 : n + 2 
    }
    
    console.log(bump(5)); // 7
    console.log(bump(5)); // 7 
    console.log(bump(5)); // 6 
    console.log(bump(5)); // 7 
    console.log(bump(5)); // 6 
    

    这里bump被调用了5次,每次都产生一个新的随机数。

    修复 checkExistence

    有两种方法。

    • 而不是生成一次值并重新使用它。每次您需要时,都会在您的投票中生成一个新的布尔值。
    function checkExistencePoll(): Observable<boolean> {
      const POLL = 5000;
      return checkExistence().pipe(
        expand(_ =>
          timer(POLL).pipe(
            switchMap(() => checkExistence()),
            takeUntil(stop),
            repeatWhen(() => start)
          )
        )
      );
    }
    
    • checkExistence 返回一个在订阅时生成新布尔值的可观察对象
    function checkExistence(): Observable<boolean> {
      return defer(() => {
        const nu = Math.random();
        const rand = nu < 0.5;
        console.log(nu, rand);
        return of(rand);
      });
    }
    

    处理订阅

    在您的代码中,expand 正在生成一个订阅主题(称为 start)的 observable,以便决定何时重复。每个可观察的expand 创建的都是这样做的。因此,当start 发出时,每个都会重复。您应该期望 batches 个布尔值等于您创建的并发 observable 的数量。

    【讨论】:

      猜你喜欢
      • 2017-03-19
      • 2021-10-04
      • 2019-01-18
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多