rxjs 和 setTimeout 的组合会产生意外的运行时行为

Combination of rxjs and setTimeout creates unexpected runtime behaviour

我在理解以下两个片段之间的区别时遇到了一些问题。

const a = Observable.create(
  o => {
    setTimeout(
      ()=>{ 
        console.log("now 3");
        o.next(3);
        setTimeout(()=>{ console.log("and now 5"); o.next(5)}, 1500);}
      , 1500);
   
  }
);
const a2 = Observable.create(
  o => {
    setTimeout(
      ()=>{ 
        console.log("here is 4");
        o.next(4);
        setTimeout(o.next(6), 1500);}
      , 1500);
  }
);

https://stackblitz.com/edit/rxjs-byqgnh?devtoolsheight=60

我在第二个块中只删除了控制台日志。

第一个块按预期工作:第一个数字在超时后发出,第二个数字也是如此。

第二个块同时发出两个数字。谁能解释一下区别?

setTimeout 回调

以下生成运行时错误

setTimeout(o.next(6), 1500);

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function.

因为 n.next 的 return 类型未定义。然而,Observables 会捕获错误并将它们作为错误事件发送给您。所以你在你的例子中看不到这一点。

要解决此问题,您可以给 setTimeout 一个回调函数。

setTimeout(() => o.next(6), 1500);

当你这样做时

setTimeout(()=>{ console.log("and now 5"); o.next(5)}, 1500);

您正在将 ()=>{ console.log("and now 5"); o.next(5)} 作为回调函数传递给 setTimeout API,这可能会在 1.5sec 之后触发。很好,因为这是你想要发生的事情。

但是当你这样做的时候

setTimeout(o.next(6), 1500)

您正在执行 o.next(6) 并在将其作为回调函数传递给 setTimeout 之前发出值,但是当您看到 It's not a function signature 时,o.next(6) 会生成什么是一个 undefined 值,它将作为回调传递,您可能会得到 Callback must be a function 错误。

因此,如果您希望 o.next(6) 作为回调函数传递给 setTimeout 并在 1.5 秒后发出值,那么您可以将其传递为

setTimeout(() => o.next(6), 1500)

setTimeout(function(){
   o.next(6);
}, 1500)