diff --git a/src/pages/node/event-loop/index.tsx b/src/pages/node/event-loop/index.tsx new file mode 100644 index 0000000..bb091db --- /dev/null +++ b/src/pages/node/event-loop/index.tsx @@ -0,0 +1,33 @@ +import { EventSystem } from "./src" + +const eventSystem = new EventSystem() + +const Eventloop = () => { + const enQueue = () => { + console.log("enQueue") + const curDate = new Date() + eventSystem.enQueue(() => { + console.log("time: " + curDate) + }) + } + + const run = () => { + console.log("run") + eventSystem.run() + } + + const end = () => { + console.log("end") + eventSystem.setStop() + } + + return ( +
+ + + +
+ ) +} + +export default Eventloop diff --git a/src/pages/node/event-loop/src/index.js b/src/pages/node/event-loop/src/index.js new file mode 100644 index 0000000..5a322f4 --- /dev/null +++ b/src/pages/node/event-loop/src/index.js @@ -0,0 +1,73 @@ +// https://juejin.cn/book/7171733571638738952/section/7174421241225281566?scrollMenuIndex=1 + +// 麻雀虽小但五脏俱全,以上代码虽然只是个 demo,但已经具备了事件循环的一些核心功能。 +// 事件循环的整体架构是一个 while 循环 +// 定义任务类型和队列,这里只有一种任务类型和一个队列,比如 Node.js 里有好几种,每种类型的任务有不同的作用。 +// 没有任务的时候怎么处理:进入阻塞状态,而不是靠忙轮询。 + +export class EventSystem { + constructor() { + // 需要处理的任务队列 + this.queue = [] + // 标记是否需要退出事件循环 + this.stop = 0 + // 有任务时调用该函数"唤醒" await + this.wakeup = null + } + + // 没有任务时,事件循环的进入"阻塞"状态 + wait() { + return new Promise((resolve) => { + // 记录 resolve,可能在睡眠期间有任务到来,则需要提前唤醒 + this.wakeup = () => { + this.wakeup = null + resolve() + } + }) + } + + // 停止事件循环,如果正在"阻塞",则"唤醒它" + setStop() { + this.stop = 1 + this.wakeup && this.wakeup() + } + + // 生产任务 + enQueue(func) { + this.queue.push(func) + this.wakeup && this.wakeup() + } + + // 处理任务队列 + handleTask() { + if (this.queue.length === 0) { + return + } + // 本轮事件循环的回调中加入的任务,下一轮事件循环再处理,防止其他任务没有机会处理 + const queue = this.queue + this.queue = [] + while (queue.length) { + const func = queue.shift() + func() + } + } + + // 事件循环的实现 + async run() { + // 如果 stop 等于 1 则退出事件循环 + while (this.stop === 0) { + // 处理任务,可能没有任务需要处理 + this.handleTask() + // 处理任务过程中如果设置了 stop 标记则退出事件循环 + if (this.stop === 1) { + break + } + // 没有任务了,进入睡眠 + if (this.queue.length === 0) { + await this.wait() + } + } + // 退出前可能还有任务没处理,处理完再退出 + this.handleTask() + } +} diff --git a/src/pages/node/index.tsx b/src/pages/node/index.tsx index 1724929..ae0f94a 100644 --- a/src/pages/node/index.tsx +++ b/src/pages/node/index.tsx @@ -1,5 +1,18 @@ -export const NodePage = () => { - return
NodePage
+import { CommonPageRouter } from "../main" +import { lazy } from "react" + +const Eventloop = lazy(() => import("./event-loop")) + +export const children = [ + { + path: "eventloop", + element: , + title: "简单版Eventloop", + }, +] + +const NodePage = () => { + return } export default NodePage diff --git a/src/pages/node/js-libuv/index.tsx b/src/pages/node/js-libuv/index.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/node/js-libuv/src/index.js b/src/pages/node/js-libuv/src/index.js new file mode 100644 index 0000000..872cf46 --- /dev/null +++ b/src/pages/node/js-libuv/src/index.js @@ -0,0 +1,6 @@ +// https://juejin.cn/book/7171733571638738952/section/7173918784720207879?scrollMenuIndex=1#heading-2 + +// js <=> c++ <=> libuv +// JS 和 C、C++ 层的通信,Node.js 很多功能都是由 C、C++ 实现,然后暴露到 JS 层使用的, +// 所以当我们调用 JS 代码时,就会进入 C++ 层,接着 C++ 层会进入 Libuv 的 C 层, +// 等到 Libuv 完成操作后就会回调 C++ 代码,最终 C++ 代码再回调 JS 层。 diff --git a/src/pages/node/mini-koa/README.md b/src/pages/node/mini-koa/README.md deleted file mode 100644 index 9bb049a..0000000 --- a/src/pages/node/mini-koa/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# my-koa - -简单手写实现koa diff --git a/src/pages/node/mini-koa/src/kob.js b/src/pages/node/mini-koa/src/kob.js index 0afdb75..a81271a 100644 --- a/src/pages/node/mini-koa/src/kob.js +++ b/src/pages/node/mini-koa/src/kob.js @@ -1,3 +1,5 @@ +简单手写实现koa + const http = require("http") const context = require("./context") const request = require("./request") @@ -50,7 +52,7 @@ class KOB { return dispatch(0) function dispatch(i) { - let fn = middlewares[i] + const fn = middlewares[i] if (!fn) { return Promise.resolve() } diff --git a/src/router/index.tsx b/src/router/index.tsx index ae2ea48..3e87b42 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -6,6 +6,7 @@ import { children as ReactChildren } from "../pages/react" import { children as AnimateChildren } from "../pages/animation" import { children as CanvasChildren } from "../pages/canvas" import { children as WebpackChildren } from "../pages/webpack" +import { children as NodeChildren } from "../pages/node" import { Suspense, lazy } from "react" import { HashRouter, Route, Routes } from "react-router-dom" import { PageRoute } from "../types" @@ -54,6 +55,7 @@ export const routes: PageRoute[] = [ path: "/node", element: , title: "node 相关", + children: NodeChildren, }, { path: "/web-rtc", @@ -84,7 +86,7 @@ export const routes: PageRoute[] = [ export const RouteContainer = () => { const genRoutes = (routes: PageRoute[]) => { - let finalRoutes = routes.map((item) => { + const finalRoutes = routes.map((item) => { const { path, element, children, index } = item return !index ? (