问题描述
我正在尝试使用 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 的数量。