我有一个有趣的例子,不是现实生活中的任务,而是:
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');
Subject.next以同步方式工作,因此如果我注释掉observeOn(queueScheduler)-它会导致堆栈溢出(我使用Take运算符控制迭代次数,如果数量大于1370,则在我的计算机上控制它-导致SO)
但是,如果我将queueScheduler放在此处-效果很好。 QueueScheduler是同步的,并以某种方式允许当前的onNext处理程序运行结束运行,然后开始下一次计划运行。
有人可以向我详细说明源代码吗?我尝试进行挖掘,但目前未取得成功。这是关于observeOn如何与QueueScheduler一起工作的,但是答案却在逃避我。
答案 0 :(得分:1)
感谢卡丹的支持。好像我了解为什么队列调度程序在没有SO的情况下工作。
当第一次从observeOn _next队列中调用signal.next时,会导致QueueAction.schedule被调用
QueueAction.flush被呼叫。 this.scheduler.flush-> QueueSchedulerFlush-> AsyncScheduler.flush
第一次队列为空,并且不执行任何任务,因此this.active为false。 action.execute的bc被调用。一切都以同步方式调用。
action.execute导致onNext函数再次运行。因此,onNext调用signal.next会遍历所有1-3点,但是现在this.active为true(因为它实际上仍然是先前的signal.next运行),我们只需queue action
因此处理了第二个signal.next,然后返回到对第一个signal.next调用执行。它可以在do-while中工作,并一一转移动作。至此,它完成了第一个signal.next动作的运行-但现在我们从第二个signal.next递归调用中又排队了。因此,我们对第二个信号运行action.execute。next
并且情况正在重复。首先,刷新调用将管理所有其他调用,例如:active为true,我们将任务添加到队列中,然后重复执行上一个刷新调用并从队列中获取它。