2024-07-11
面试相关
00

目录

Node.js的运行机制
事件循环(Event Loop)
Node.js的单线程模型如何处理高并发请求
Node.js 中的模块
模块分类
模块导入
模块的初始化
模块加载机制
Koa框架
Egg框架

Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。将libuv作为跨平台抽象层,libuv是用c/c++写成的高性能事件驱动的程序库。nodejs的原理类似c/c++系统编程中的epoll

Node.js的运行机制

image.png

(1)V8引擎解析JavaScript脚本。

(2)解析后的代码,调用Node API。

(3)libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。

(4)V8引擎再将结果返回给用户。

  • node.js的主进程和Event Loop是分开的,主进程执行完同步代码就不执行了,剩下的就交给事件循环去做了。

事件循环(Event Loop)

nodejs 执行之后会初始化一个事件循环,执行代码程序(这些程序可能会造成异步调用、定时器或者process.nextTick()),然后开始执行事件循环。

image.png

上边的每一个模块都是事件循环的一个阶段,每个阶段都有一个要执行的回调的FIFO队列。虽然每个阶段都不同,一般来说,当事件执行到一个阶段,先执行这个阶段特有的操作,然后操作这个阶段的队列,当队列执行完或者达到了回调上限,事件循环就会执行下一个阶段。

小结:poll队列为空的时候,事件循环有可能执行check阶段执行setImmediate的回调,也有可能回到timer阶段执行setTimeout的回调,这取决于setImmediate和setTimeout的回调哪个到得早。

Node.js的单线程模型如何处理高并发请求

Node.js采用单线程模型,但通过事件循环和异步I/O操作,可以处理大量的并发请求。Node.js的事件循环是单线程的,但是通过内部的libuv库进行异步I/O操作,它可以同时处理数以万计的并发连接。

Node.js 中的模块

模块分类

  1. 具名的核心模块(已经封装好的内置模块,http、fs、os 等)
  2. 自定义模块
  3. 第三方模块(npm下载下来的,express、art-template 等)

模块导入

  • 使用require方法导入模块

    注意:requier函数有两个作用:

    执行导入的模块中的代码 返回导入模块中的接口对象 module.exports
  • 导入自定义模块时,require 参数是模块的路径。例如:const getDir = require(‘./getDir’)

    路径中后缀名 .js 可以省略 相对路径"./xxx",不能省略 “./”,表示当前路径下的 xxx 文件 绝对路径"/xxx",表示当前磁盘根目录下的 xxx 文件,其中"/" 表示当前磁盘根目录
  • 导入具名的核心模块,require 参数直接写模块名即可。例如:const http = require(‘http’)

  • 导入第三方包时,require 参数就是下载第三方包时的包名。例如:const express = require(‘express’)

  • require 优先从缓存中加载模块,从缓存中加载时不会执行模块中的代码

模块的初始化

一个模块中的JS代码仅在模块第一次被使用时执行一次,并且在使用的过程中进行初始化,之后缓存起来便于后续继续使用。

模块加载机制

内置模块的加载优先级最高,例如 require(‘http’) 始终会返回内置的 fs 模块,即使在 node_modules 目录下有相同的包名叫 fs。

内置模块或者第三方模块,直接require 模块名即可。对于自定义模块,必须指定以 ./ 或 …/ 开头的路径标识符。

同时,在使用 require 导入自定义模块时,可以省略文件的扩展名。此时,Node.js 会按以下顺序分别尝试加载文件:

  • 按照确切的文件名进行加载
  • 补全 .js 扩展名进行加载
  • 补全 .json 扩展名进行加载
  • 补全 .node 扩展名进行加载
  • 如果以上都没有加载成功,则终端报错

Koa框架

洋葱模型中间件机制

  1. 异步编程风格

Koa框架使用异步编程风格,通过使用Promise或async/await等机制来处理异步操作。相比传统的回调方式,异步编程使得代码更加清晰、易于维护,并且能够避免回调地狱的问题。

  1. 简洁、灵活的中间件机制

Koa的核心思想是中间件,它允许开发者通过编写各种中间件来处理请求和响应。每个中间件可以单独执行特定的任务,也可以将控制权传递给下一个中间件。这种中间件的处理流程类似于洋葱模型,非常灵活。

  1. 生成器函数的利用

Koa使用ES6中的生成器函数(Generator Function)来实现中间件的处理流程。生成器函数可以通过yield关键字暂停和恢复执行,这样就可以方便地实现中间件的串联和控制流程。生成器函数的特性使得编写和理解中间件变得更加简单和直观。

  1. 上下文对象的封装

在Koa中,每个请求都会创建一个上下文对象(Context),它封装了请求和响应的相关信息,并提供了一些方便的方法来操作和获取请求和响应的内容。上下文对象还可以在中间件之间传递数据和状态,使得开发者能够更好地组织和管理代码。

Egg框架

  • 基于Koa的封装、‌整合了数据库、‌路由等中间件
  • 通过插件机制扩展功能
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:seek

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!