微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 rxjs 中使用 expand 进行轮询会产生意想不到的结果 一个简化的例子

如何解决在 rxjs 中使用 expand 进行轮询会产生意想不到的结果 一个简化的例子

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

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

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

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

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

解决方法

这真的不是一个问题。

赋值/函数调用

一个简化的例子

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

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 返回一个可在订阅时生成新布尔值的 observable
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,以便决定何时重复。每个 observable expand 创建都这样做。所以当 start 发出时,每一个都会重复。您应该期望 batches 布尔值等于您创建的并发 observables 的数量。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。