rx.js 6.3中的queueScheduler是同步的-如果我使用queueScheduler,为什么此示例不会导致SO?

时间:2018-10-20 11:22:07

标签: rxjs

我有一个有趣的例子,不是现实生活中的任务,而是:

const signal = new Subject();
let count = 0;

const somecalculations = (count) => console.log('do some calculations with ', count);


console.log('Start');
signal.pipe(take(1500)/*, observeOn(queueScheduler)*/)
  .subscribe(() => {
  somecalculations(count);
  signal.next(count++);
  console.log('check if reached ', count)
});

signal.next(count++);
console.log('Stop');

codepen

Subject.next以同步方式工作,因此如果我注释掉observeOn(queueScheduler)-它会导致堆栈溢出(我使用Take运算符控制迭代次数,如果数量大于1370,则在我的计算机上控制它-导致SO)

但是,如果我将queueScheduler放在此处-效果很好。 QueueScheduler是同步的,并以某种方式允许当前的onNext处理程序运行结束运行,然后开始下一次计划运行。

有人可以向我详细说明源代码吗?我尝试进行挖掘,但目前未取得成功。这是关于observeOn如何与QueueScheduler一起工作的,但是答案却在逃避我。

observeOn src QueueScheduler.ts asyncScheduler

1 个答案:

答案 0 :(得分:1)

感谢卡丹的支持。好像我了解为什么队列调度程序在没有SO的情况下工作。

  1. 当第一次从observeOn _next队列中调用signal.next时,会导致QueueAction.schedule被调用

  2. QueueAction.flush被呼叫。 this.scheduler.flush-> QueueSchedulerFlush-> AsyncScheduler.flush

  3. 第一次队列为空,并且不执行任何任务,因此this.active为false。 action.execute的bc被调用。一切都以同步方式调用。

  4. action.execute导致onNext函数再次运行。因此,onNext调用signal.next会遍历所有1-3点,但是现在this.active为true(因为它实际上仍然是先前的signal.next运行),我们只需queue action

  5. 因此处理了第二个signal.next,然后返回到对第一个signal.next调用执行。它可以在do-while中工作,并一一转移动作。至此,它完成了第一个signal.next动作的运行-但现在我们从第二个signal.next递归调用中又排队了。因此,我们对第二个信号运行action.execute。next

  6. 并且情况正在重复。首先,刷新调用将管理所有其他调用,例如:active为true,我们将任务添加到队列中,然后重复执行上一个刷新调用并从队列中获取它。