使用 rxjs asapscheduler 的执行顺序

问题描述

考虑到我有以下代码

let Rx = window['rxjs'];
const { of,queueScheduler,asapScheduler,asyncScheduler,animationFrameScheduler
} = Rx;
const { observeOn,tap } = Rx.operators;
console.clear();


let source$ = of(1,2,3,asapScheduler).pipe(
    tap((v) => {
        console.log('tap ',v);
    }),)

source$.subscribe((v) => {
    console.log('Value ',v);
    Promise.resolve().then(() => {
        console.log('Microtask value ',v);
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.2.1/rxjs.umd.js"></script>

我使用 asapScheduler 运算符。

根据文档,

asap 将等待当前同步执行的代码结束,然后它会尝试尽快执行给定的任务。

上面代码的执行顺序是什么?它们是如何工作的?我没想到 tap3 会在最后打印

下面是输出

tap  1
Value  1  
tap  2    // here why did this not print Microtask value 1 and Microtask value 2 after printing tap1 and value1?
Value  2
Microtask value  1
Microtask value  2
tap  3
Value  3
Microtask value  3

解决方法

据我所知,RxJS 倾向于使用独立的调度程序。它按预期工作:

let source$ = of(1,2,3).pipe(
    tap((v) => {
        console.log('tap ',v);
    }),)

source$.subscribe((v) => {
    asapScheduler.schedule(() => console.log('Value ',v));
    asyncScheduler.schedule(() => Promise.resolve().then(() => {
        console.log('Microtask value ',v);
    }))
})

另一个含义,如果你在你的 observable 中使用 scheduler,比如 Of(...,asapScheduler), - 它需要你的 observable 的完整路径流,从创建到订阅结束,并尝试尽快调用它。在您的微任务示例中,看起来很合理。

,

涉及的步骤:

  1. of 根据调度程序(本例中的下一个宏任务)发出第一个值
  2. 它将下一个值放入调度程序队列(微任务)
  3. 接下来的每个排放都重复第 1 步和第 2 步。

控件打印当前宏任务,

1.) tap1 和 值1

按照第二步, 2.) tap2 和 value2 执行并完成所有挂起的 asap 和 async 任务,如下所示,

3.) 微任务值 1 和微任务值 2

按照第三步,

它再次遵循下面的第一步,

4.) 点击 3 和值 3

按照第二步, 执行 tap4 和 value4 并完成所有挂起的 asap 和 async 任务,如下所示,

微任务值 3 微任务值 4

要深入了解此article