试图解开Node JS事件循环的几个实验之谜

问题描述 投票:0回答:1

在制作了一些小功能组件之后,我继续对事件循环进行一些测试。 需要实验 NO -1 2 和 3 的帮助,并想知道它们的输出是如何得出的。

从此播放列表中学习了事件循环: 播放列表

参考图片,我关注了

我为进行实验而制作的图书馆

//functional programmed library for testing eventloop.
import { readFile, createReadStream } from "fs";

type callback = () => void;

function logger(txt: string) {
  console.log(txt);
}

function sleep(time?: number) {
  const start = Date.now();
  while (Date.now() - start < (time ? time : 500)) {
    continue;
  }
  console.log("wake up! ⏰");
}

function io(cb: callback): void {
  readFile(__filename, cb);
};

function tick(cb: callback): void {
  process.nextTick(cb);
}

function promise(cb: callback): void {
  Promise.resolve().then(cb);
}

function close(cb: callback): void {
  const stream = createReadStream(__filename);
  stream.close();
  stream.on("close", cb);
}

function timeout(cb: callback): void {
  setTimeout(cb, 0);
}

function checker(cb: callback): void {
  setImmediate(cb);
}

function bounce(set: Set<string>, source: string): () => void {
  return () => {
    console.log(`______${source}_______`);
    if (set.has("checker")) checker(() => { logger("checker"); });
    if (set.has("timeout")) timeout(() => { logger("timeout"); });
    if (set.has("close")) close(() => { logger("close"); });
    if (set.has("tick")) tick(() => { logger("tick"); });
    if (set.has("promise")) promise(() => { logger("promise"); });
    if (set.has("io")) io(() => { logger("io"); });
    sleep(1000);
  };
}

免责声明:以下所有实验均作为单个单元进行,并通过使用 sleep 函数阻塞调用堆栈 1 秒,确保在事件循环开始之前推送所有回调。

实验-0:展示我在其他实验中期望的顺序

io(bounce(new Set(["checker", "close"]), "io"));
timeout(() => logger("timeout"));
tick(() => logger("tick"));
promise(() => logger("promise"));

Exp0 的输出:

tick
promise
timeout
io
checker
close

实验一:

io(bounce(new Set(["checker", "close", "timeout"]), "io"));

预期输出:

______io_______
checker
close
timeout

实际输出:

______io_______
checker
timeout
close

实验2:

close(bounce(new Set(["timeout", "checker", "io"]), "close"));

预期输出:

______close_______
timeout
checker
io

实际输出:

______close_______
checker
timeout
io

实验3:

checker(bounce(new Set(["close", "io", "timeout"]), "checker"));

预期输出:

______checker_______
close
timeout
io

实际输出:

______checker_______
timeout
close
io

我只是期待我的实验得到澄清,为什么它们没有我想要的实验 1,2 和 3 的预期输出。因为根据该播放列表的教学和参考图像节点 JS 应该打印我的预期输出。

javascript node.js event-loop
1个回答
0
投票

因此,如 Node.js 文档 和参考视频中所示,执行顺序是:
计时器 -> IO 回调 -> IO 轮询 -> 检查 -> 关闭回调
对吗?

这里的问题是,

const stream = createReadStream(__filename);
stream.close();
stream.on("close", cb);

这不会添加到您的关闭队列中;它实际上是在进行 IO 轮询。

让我解释一下你的第一个实验: 您已将检查器、关闭和超时放入 IO 回调中。

  1. 当IO回调完成后,会增加两个回调:一个是checker,一个是timeout。不过,正如我所说,close实际上是IO轮询。 (打印:______ io______)
  2. IO 轮询可读流并向 IO 队列添加回调。
  3. 检查器回调执行(打印:检查器)
  4. 关闭队列中没有回调;移至计时器
  5. 计时器回调执行(打印:超时)
  6. 循环继续,现在将执行一个 IO 回调(来自步骤 2)(打印:close)。

现在,您也可以用同样的方式检查其他实验。
我希望这对你有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.