首页 > 解决方案 > rxjs 和 setTimeout 的组合会产生意外的运行时行为

问题描述

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

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

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

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

第二个块同时发出两个数字。任何人都可以解释其中的区别吗?

标签: javascriptasynchronousrxjs

解决方案


当你这样做

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,但是当您看到它不是函数签名时,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)

推荐阅读