• 忘掉天地
  • 仿佛也想不起自己
  • 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2025-04-03 18:11 Aet 隐藏边栏 |   抢沙发  4 
文章评分 1 次,平均分 5.0

安装node.js

安装

  1. Node.js

验证

其他设置1

镜像

  1. 找到 npm 配置文件:
    1. WindowsC:\Users\<用户名>\.npmrc
    2. Mac/Linux~/.npmrc
  2. 用文本编辑器打开 .npmrc,添加以下内容:

  1. 保存文件并重启终端
  2. 清理缓存并重试
    1. 可能需要

  1. 通过以下命令检查配置是否生效:
    1. electron_mirror=https://npmmirror.com/mirrors/electron/ 表示配置成功

代理

  1. 若使用 VPN 或企业代理,需在 .npmrc 中添加代理设置:

创建应用程序

初始化 npm 项目

Electron 安装为项目的 devDependencies

  1. 仅在开发环境需要的额外依赖
    1. 输出如下:

运行 Electron 应用

  1. main.js

  1. package.json
    1. 要执行这个脚本,需要在 package.jsonscripts 字段中添加一个 start 命令,内容为 electron .
    2. 这个命令会告诉 Electron 在当前目录下寻找主脚本,并以开发模式运行它

  1. 终端执行:

将网页装载到 BrowserWindow

  1. Electron 中,每个窗口展示一个页面,后者可以来自本地的 HTML,也可以来自远程 URL
    1. 在项目的根目录中创建一个 index.html 文件,并写入下面的内容:

修改main.js

  1. 第一行中,我们使用 CommonJS 语法导入了两个 Electron 模块:
    1. app,这个模块控制着您应用程序的事件生命周期
    2. BrowserWindow,这个模块创建和管理 app 的窗口

  1. Electron 的许多核心模块都是 Node.js事件触发器,遵循 Node.js 的异步事件驱动架构
    1. app 模块就是其中一个
    2. Electron 中,只有在 app 模块的 ready 事件(event)触发后才能创建 BrowserWindows 实例
    3. 可以通过使用 app.whenReady() API 来监听此事件,并在其成功后调用 createWindow() 方法

关于页面

  1. 应用中的每个页面都在一个单独的进程中运行,我们称这些进程为 渲染器 (renderer)
  2. 渲染进程使用与常规Web开发相同的JavaScript API和工具

管理应用的窗口生命周期

概述

  1. 应用窗口在不同操作系统中的行为也不同
  2. Electron 允许您自行实现这些行为来遵循操作系统的规范,而不是采用默认的强制执行
  3. 可以通过监听 appBrowserWindow 模组的事件,自行实现基础的应用窗口规范

针对特定平台

  1. 通过检查 Node.jsprocess.platform 变量,您可以针对特定平台运行特定代码

关闭所有窗口时退出应用 (Windows & Linux)

  1. WindowsLinux 上,我们通常希望在关闭一个应用的所有窗口后让它退出
  2. 可以监听 app 模块的 window-all-closed 事件,并在判断用户不使用 macOS 后调用 app.quit() 来退出您的应用程序

没有窗口打开则打开一个窗口 (macOS)

  1. 与前二者相比,即使没有打开任何窗口,macOS 应用通常也会继续运行
    1. 在没有窗口可用时调用 app 会打开一个新窗口
    2. 可以监听 app 模组的 activate 事件,如果没有任何打开(open)的 BrowserWindow,调用您已有的createWindow() 方法新建一个

VSCode里面调试

  1. 在根目录新建一个 .vscode 文件夹,然后在其中新建一个 launch.json 配置文件并填写如下内容

DevTools调试

Node.js 的异步事件驱动架构

概述

  1. Node.js 的异步事件驱动架构是其高效处理高并发的核心机制,结合了非阻塞 I/O、事件循环(Event Loop)和事件驱动的编程模型

V8

  1. 负责解析和执行 JavaScript 代码,将代码编译为机器指令
  2. 与底层系统直接交互,提升性能

libuv

  1. 跨平台异步 I/O 库,提供事件循环、线程池和文件系统操作的非阻塞实现
  2. 管理事件循环的 6 个阶段(timerspollcheck 等),协调异步任务调度

事件循环(Event Loop

  1. 单线程模型:
    1. 主线程仅负责事件调度,避免多线程上下文切换的开销
  2. 非阻塞 I/O
    1. 通过回调函数或 Promise 处理耗时操作(如文件读写、网络请求),主线程无需等待 I/O 完成

事件循环的详细阶段

  1. 概述
    1. 事件循环按顺序执行以下阶段,每个阶段处理特定类型的任务
  2. Timers 阶段
    1. 执行 setTimeoutsetInterval 的回调
  3. Pending I/O Callbacks
    1. 处理上一轮未完成的 I/O 回调(如 TCP 错误)
  4. Idle/Prepare
    1. 系统内部使用
  5. Poll 阶段
    1. 核心阶段:检索新的 I/O 事件(如文件读取完成、HTTP 请求到达),执行关联的回调
    2. 若队列为空,则阻塞等待新事件,或跳转到 Check 阶段
  6. Check 阶段
    1. 执行 setImmediate 的回调
  7. Close Callbacks
    1. 处理关闭事件(如 socket.on('close')

异步任务的分类与优先级

  1. 宏任务(Macrotask
    1. 包括 setTimeoutsetIntervalI/O 操作、setImmediate
    2. 每个事件循环阶段执行一个宏任务
  2. 微任务(Microtask
    1. 包括 Promise.thenprocess.nextTick
    2. process.nextTick 在事件循环各阶段之间立即执行(优先级最高)
    3. Promise 回调在宏任务结束后执行

事件驱动模型的核心机制

  1. EventEmitter
    1. 实现发布-订阅模式,通过 .on() 注册事件监听器,.emit() 触发事件

非阻塞 I/O 的工作流程

  1. 主线程发起 I/O 请求后,立即继续执行后续代码
  2. I/O 完成后,libuv 将回调推入事件队列,事件循环在 Poll 阶段执行回调

单线程与事件循环

  1. Node.js 主线程运行 V8 引擎解析 JavaScript,同步代码直接执行,异步任务(如 I/O、定时器)通过 libuv 提交到事件循环队列
    1. 主线程通过 事件循环(Event Loop) 调度任务,避免阻塞
  2. libuv 的协作
    1. 任务分发:Node.js 主线程将异步任务(如 fs.readFile)委托给 libuv,后者通过线程池或系统内核的异步接口(如 epoll)处理
    2. 回调触发:任务完成后,libuv 将回调推入事件队列,主线程在轮询到对应阶段时执行回调

问题

  1. libuv 是否维护自己的事件队列?
    1. 是的,libuv 维护独立的事件队列,但它的队列结构是分阶段的
    2. libuv 的事件循环分为 6 个阶段(如 Timers 阶段、Poll 阶段、Check 阶段等),每个阶段对应一个特定类型的事件队列
      Timers 队列:存放 setTimeout/setInterval 的回调
      I/O 队列:存放已完成的 I/O 操作(如文件读写、网络请求)的回调
      Check 队列:存放 setImmediate 的回调
    3. 当异步任务(如文件 I/O)完成时,libuv 的线程池会将回调推入对应阶段的队列,等待事件循环轮询到该阶段时执行
  2. 主线程是否有自己的事件队列?
    1. 主线程没有独立的事件队列,但 Node.js 主线程的事件循环与 libuv 的事件队列紧密绑定
      具体来说:
      主线程的事件循环直接管理 libuv 的事件队列
      当主线程空闲时,会通过事件循环(uv_run)依次轮询 libuv6 个阶段队列,并执行其中的回调
    2. 微任务队列:主线程还有两个特殊的中间队列(不属于 libuv):
      nextTick 队列:存放 process.nextTick 的回调,优先级最高
      Microtask 队列:存放 Promise 的回调,优先级次之
      这两个队列会在每个 libuv 阶段切换时优先清空
  3. 主线程有没有任务队列?
    1. nextTick 队列Microtask 队列属于 Node.js 主线程自身的任务队列
  4. 回调的执行者是 libuv 还是主线程?
    1. 回调由主线程执行,但 libuv 负责调度:
    2. libuv 线程池:处理耗时任务(如文件 I/ODNS 解析),完成后将回调推入对应阶段的队列
    3. 主线程的事件循环:在轮询到对应阶段时,从 libuv 队列中取出回调并执行
  5. 主程序处理任务的优先级?
    1. 同步代码
    2. nextTick 队列
    3. Microtask 队列
    4. libuv 阶段队列(如 TimersI/O

总结(记忆)

  1. node.js主线程运行着一个事件循环,还有两个自己的任务队列nextTickMicrotask
  2. v8引擎负责解析执行JavaScript代码,同步代码直接在主线程执行,异步代码交给libuv处理
  3. libuv维护了6个阶段队列,这6个队列存放相应任务的对应的回调 node.js主线程在空闲时候,按优先级取出这些队列中的回调(nextTick,Microtasklibuv阶段队列)并执行

事件触发器

EventEmitter

  1. Node.jsevents 模块提供了 EventEmitter 类,所有能触发事件的对象均是该类的实例
  2. 通过 on() 方法注册监听器(订阅事件),emit() 方法触发事件(发布事件)

事件驱动的异步模型

  1. 异步模型见上述

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2025-04-05
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享