当前位置: 首页 > news >正文

91 # 实现 express 的优化处理

上一节实现 express 的请求处理,这一节来进行实现 express 的优化处理

  1. 让 layer 提供 match 方法去匹配 pathname,方便拓展
  2. 让 layer 提供 handle_request 方法,方便拓展
  3. 利用第三方库 methods 批量生成方法
  4. 性能优化问题
    • 进行路由懒加载,当进行 get/post... 请求时,或者 listen 时,才加载 route
    • layer 进行加速匹配,在 layer 层判断是否请求方法在 route 里有

methods 库地址:https://www.npmjs.com/package/methods

['acl',        'bind',        'checkout','connect',    'copy',        'delete','get',        'head',        'link','lock',       'm-search',    'merge','mkactivity', 'mkcalendar',  'mkcol','move',       'notify',      'options','patch',      'post',        'pri','propfind',   'proppatch',   'purge','put',        'rebind',      'report','search',     'source',      'subscribe','trace',      'unbind',      'unlink','unlock',     'unsubscribe'
]

批量生成方法测试 demo 如下

const express = require("./kaimo-express");
const app = express();app.get("/", (req, res, next) => {res.end("get okk end");
});
app.post("/", (req, res, next) => {res.end("post okk end");
});app.listen(3000, () => {console.log(`server start 3000`);console.log(`在线访问地址:http://localhost:3000/`);
});

控制台执行下面命令:

curl -v -X POST http://localhost:3000/

在这里插入图片描述

layer 进行加速匹配 demo

const express = require("./kaimo-express");
const app = express();app.post("/", (req, res, next) => {res.end("post okk end");
});
app.put("/", (req, res, next) => {res.end("put okk end");
});
app.delete("/", (req, res, next) => {res.end("delete okk end");
});
app.options("/", (req, res, next) => {res.end("delete okk end");
});app.listen(3000, () => {console.log(`server start 3000`);console.log(`在线访问地址:http://localhost:3000/`);
});

然后去访问:http://localhost:3000/,可以看到没有优化的时候会请求这些方法

在这里插入图片描述
优化之后可以看到就没有请求了

在这里插入图片描述

优化的代码如下:

application.js

const http = require("http");
const Router = require("./router");
const methods = require("methods");
console.log("methods----->", methods);function Application() {}// 调用此方法才开始创建,不是创建应用时直接装载路由
Application.prototype.lazy_route = function () {if (!this._router) {this._router = new Router();}
};methods.forEach((method) => {Application.prototype[method] = function (path, ...handlers) {this.lazy_route();this._router[method](path, handlers);};
});Application.prototype.listen = function () {const server = http.createServer((req, res) => {function done() {res.end(`kaimo-express Cannot ${req.method} ${req.url}`);}this.lazy_route();this._router.handle(req, res, done);});server.listen(...arguments);
};module.exports = Application;

router/index.js

const url = require("url");
const Route = require("./route");
const Layer = require("./layer");
const methods = require("methods");function Router() {// 维护所有的路由this.stack = [];
}Router.prototype.route = function (path) {// 产生 routelet route = new Route();// 产生 layer 让 layer 跟 route 进行关联let layer = new Layer(path, route.dispatch.bind(route));// 每个路由都具备一个 route 属性,稍后路径匹配到后会调用 route 中的每一层layer.route = route;// 把 layer 放到路由的栈中this.stack.push(layer);return route;
};methods.forEach((method) => {Router.prototype[method] = function (path, handlers) {// 1.用户调用 method 时,需要保存成一个 layer 当道栈中// 2.产生一个 Route 实例和当前的 layer 创造关系// 3.要将 route 的 dispatch 方法存到 layer 上let route = this.route(path);// 让 route 记录用户传入的 handler 并且标记这个 handler 是什么方法route[method](handlers);};
});Router.prototype.handle = function (req, res, out) {console.log("请求到了");// 需要取出路由系统中 Router 存放的 layer 依次执行const { pathname } = url.parse(req.url);let idx = 0;let next = () => {// 遍历完后没有找到就直接走出路由系统if (idx >= this.stack.length) return out();let layer = this.stack[idx++];// 需要判断 layer 上的 path 和当前请求路由是否一致,一致就执行 dispatch 方法if (layer.match(pathname)) {// 将遍历路由系统中下一层的方法传入// 加速匹配,如果用户注册过这个类型的方法在去执行if (layer.route.methods[req.method.toLowerCase()]) {layer.handle_request(req, res, next);} else {next();}} else {next();}};next();
};module.exports = Router;

route.js

const Layer = require("./layer");
const methods = require("methods");function Route() {this.stack = [];// 用来描述内部存过哪些方法this.methods = {};
}Route.prototype.dispatch = function (req, res, out) {// 稍后调用此方法时,回去栈中拿出对应的 handler 依次执行let idx = 0;console.log("this.stack----->", this.stack);let next = () => {// 遍历完后没有找到就直接走出路由系统if (idx >= this.stack.length) return out();let layer = this.stack[idx++];console.log("dispatch----->", layer.method);if (layer.method === req.method.toLowerCase()) {layer.handle_request(req, res, next);} else {next();}};next();
};
methods.forEach((method) => {Route.prototype[method] = function (handlers) {console.log("handlers----->", handlers);handlers.forEach((handler) => {// 这里的路径没有意义let layer = new Layer("/", handler);layer.method = method;// 做个映射表this.methods[method] = true;this.stack.push(layer);});};
});module.exports = Route;

layer.js

function Layer(path, handler) {this.path = path;this.handler = handler;
}Layer.prototype.match = function (pathname) {return this.path === pathname;
};
Layer.prototype.handle_request = function (req, res, next) {this.handler(req, res, next);
};
module.exports = Layer;

相关文章:

91 # 实现 express 的优化处理

上一节实现 express 的请求处理,这一节来进行实现 express 的优化处理 让 layer 提供 match 方法去匹配 pathname,方便拓展让 layer 提供 handle_request 方法,方便拓展利用第三方库 methods 批量生成方法性能优化问题 进行路由懒加载&#…...

arcgis拓扑检查实现多个矢量数据之间消除重叠区域

目录 环境介绍: 操作任务: 步骤: 1、数据库和文件结构准备 2、建立拓扑规则 3、一直下一页默认参数后,进行拓扑检查 4、打开TP_CK_Topology,会自动带出拓扑要素,红色区域为拓扑错误的地方&#xff1…...

基于Vue+ELement搭建登陆注册页面实现后端交互

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《ELement》。🎯🎯 &#x1…...

JS获取经纬度, 并根据经纬度得到城市信息

在JavaScript中,获取经纬度通常需要使用定位服务,比如HTML5的Geolocation API。然而拿到坐标后,将经纬度转换为城市信息,则需要使用逆地理编码服务接口,比如百度或者高德的 API, 但是他们收费都很高, 我们可以使用一些…...

mac m1 docker安装nacos

文章目录 引言I m1安装docker1.1 Docker 下载1.2 终端Docker相关命令II docker安装nacos2.1 安装nacos2.2 镜像启动see alsoMac 查看进程端口引言 使用docker方式安装是最方便的 I m1安装docker 1.1 Docker 下载 https://docs.docker.com/docker-for-mac/apple-silicon/点击…...

位段 联合体 枚举

Hello好久不见,今天分享的是接上次结构体没有分享完的内容,这次我们讲讲位段 枚举和联合体的概念以及他们的用法。 2.1 什么是位段 位段的声明和结构是类似的,有两个不同: 1.位段的成员必须是 int、unsigned int 或signed int 。 …...

PHP循环获取Excel表头字母A-Z,当超过时输出AA,AB,AC,AD······

PHP循环获取Excel表头字母A-Z,当超过时输出AA,AB,AC,AD PHP循环生成Excel的列字母表 $count_num 26 * 27; $letter A; $arr []; while($count_num--){$arr[] $letter;$letter; }结果如下: 转为JSON更为直观: ["A","B&…...

识别准确率达 95%,华能东方电厂财务机器人实践探索

摘 要:基于华能集团公司大数据与人工智能构想理念,结合东方电厂实际工作需要,财务工作要向数字化、智能化纵深推进,随着财务数字化转型和升级加速,信息化水平不断提升,以及内部信息互联互通不断加深&#x…...

代码随想录算法训练营 单调栈part03

一、柱状图中最大的矩形 84. 柱状图中最大的矩形 - 力扣(LeetCode) 单调栈很重要的性质,就是单调栈里的顺序,是从小到大还是从大到小。 栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度&#x…...

使用 MyBatisPlus 的注解方式进行 SQL 查询,它结合了条件构造器(Wrapper)和自定义 SQL 片段来构建查询语句。

MyBatis-Plus 是一个基于 MyBatis 的增强工具,它提供了一套方便的注解方式来进行 SQL 查询。其中,它结合了条件构造器(Wrapper)和自定义 SQL 片段来构建查询语句。 官网:条件构造器 | MyBatis-Plus 1、使用 Wrapper …...

Python中统计单词出现的次数,包含(PySpark方法)

思路: 定义一个函数,使用open函数,将文本内容打开。 定义一个空字典和空列表,进行循环及条件判断操作def count_word(file_path):dict_data {} #定义一个空字典f open(file_path,"r",encoding"UTF-8")lis…...

探讨基于IEC61499 的分布式 ISA Batch 控制系统

ISA SP88 是批次过程控制的标准,对应的IEC标准是IEC 61512。该标准中一个重要的部分是配方管理(Recipe Management)。 所谓配方,是根据批量产品的要求,材料设定加工工艺,加工流程和参数。类似于传统制造业的…...

图论16(Leetcode863.二叉树中所有距离为K的结点)

答案&#xff1a; /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/ class Solution {public List<Integer> distanceK(TreeNode root, TreeNode tar…...

【小沐学C++】C++ MFC中嵌入64位ActiveX控件(VS2017)

文章目录 1、简介1.1 MFC1.2 ActiveX 2、VS2017添加ActiveX控件结语 1、简介 1.1 MFC Microsoft 基础类 (MFC) 库针对大部分 Win32 和 COM API 提供面向对象的包装器。 虽然此包装器可用于创建极为简单的桌面应用程序&#xff0c;但当你需要开发具有多个控件的更复杂的用户界…...

Linux常用命令—find命令大全

文章目录 一、find命令常用功能1、find命令的基本信息如下。2、按照文件名搜索3、按照文件大小搜索4、按照修改时间搜索5、按照权限搜索举例&#xff1a;6、按照所有者和所属组搜索7、按照文件类型搜索8、逻辑运算符 一、find命令常用功能 1、find命令的基本信息如下。 命令名…...

form组件的封装(element ui ) 简单版本

当你使用Vue.js构建Web应用时&#xff0c;封装可复用组件是提高开发效率和代码可维护性的关键之一。在这篇文章中&#xff0c;我们将探讨如何使用Vue.js来创建一个通用的表单组件&#xff0c;以及如何将它封装成一个可配置的组件。 实现思路 拿下表单模板一个个的改造&#x…...

树形DP杂题

引 对老师布置的题目稍微记录一下吧 也算对树形 D P DP DP 的巩固 T1 Ostap and Tree 题目传送门 由于有 距离 k 距离k 距离k 的限制&#xff0c;设计二维 d p dp dp 设计状态&#xff1a; f i , j : i 的子树内&#xff0c;离 i 最近的染色点与 i 距离为 j 且若 j <…...

Webpack使用plugin插件自动在打包目录生成html文件

我们使用html-webpack-plugin插件可以自动在打包代码目录生成html文件 使用步骤&#xff1a; 一、安装依赖 在控制台中输入如下代码&#xff1a; npm i -D html-webpack-plugin 二、在webpack.config.js中配置插件 const HTMLPlugin require("html-webpack-plugin&q…...

图像处理与计算机视觉--第一章-计算机视觉简介-10问

第一章-计算机视觉简介-10问 1.CV与AI的关系是什么? CV(Computer Vision)是Al的子领域&#xff0c;它致力于使计算机能够理解和解释图像和数据&#xff0c;CV借助AI技术&#xff0c;比如深度学习/机器学习&#xff0c;实现目标识别,分析和处理任务。AI提供了CV所需要的算法…...

LeetCode 80. 删除有序数组中的重复项 II

文章目录 一、题目二、Java 题解 一、题目 给你一个有序数组 nums&#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用…...

【前端面试题】浏览器面试题

文章目录 前言一、浏览器面试问题1.cookie sessionStorage localStorage 区别2.如何写一个会过期的localStorage&#xff0c;说说想法2.如何定时删除localstorage数据2.localStorage 能跨域吗2.memory cache 如何开启2.localstorage的限制2.浏览器输入URL发生了什么2.浏览器如何…...

PHP 生成 PDF文件

参考官网 Example 009 : Image() TCPDF laravel 可以使用 composer 安装 tecnickcom/tcpdf 进行使用 //require_once("../app/Extend/tcpdf/tcpdf.php"); $pdf new TCPDF();// 设置文档信息$pdf->SetCreator(懒人开发网);$pdf->SetAuthor(懒人开发网);$…...

讲讲项目里的仪表盘编辑器(一)

需求 要做一个仪表盘系统&#xff0c;要求有&#xff1a; ① 设计功能&#xff08;包括布局、大小、排列&#xff09; ② 预览功能 ③ 运行功能 布局选择 做编辑器&#xff0c;肯定要先选择布局。 前端有几种常用布局。 静态布局 也叫文档布局。默认的网页形式…...

解决方案 | 如何构建市政综合管廊安全运行监测系统?

如何构建市政综合管廊安全运行监测系统&#xff1f;WITBEE万宾城市生命线智能监测仪器&#xff0c;5年免维护设计&#xff0c;集成10多项结构与气体健康监测指标&#xff0c;毫秒级快速响应&#xff0c;时刻感知综合管廊运行态势...

JCEF中js与java交互、js与java相互调用

jcef中js与java相互调用&#xff0c;java与js相互调用&#xff0c;chrome与java相互调用&#xff0c;java与chrome相互调用、jcef与java相互调用 前提&#xff1a;https://blog.csdn.net/weixin_44480167/article/details/133170970&#xff08;java内嵌浏览器CEF-JAVA、jcef、…...

9.20 校招 实习 内推 面经

绿泡*泡&#xff1a; neituijunsir 交流裙 &#xff0c;内推/实习/校招汇总表格 1、校招丨智行者2024年校园招聘正式启动啦 校招丨智行者2024年校园招聘正式启动啦 2、校招 | 乐动机器人2024校园招聘 校招 | 乐动机器人2024校园招聘 3、校招丨小天才2024届秋季校园招聘 …...

基于JAVA+SpringBoot+Vue+协同过滤算法+爬虫的前后端分离的租房系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着城市化进程的加快…...

【Android Framework系列】第16章 存储访问框架 (SAF)

1 概述 Android 4.4&#xff08;API 级别 19&#xff09;引入了存储访问框架 (Storage Access Framework)。SAF让用户能够在其所有首选文档存储提供程序中方便地浏览并打开文档、图像以及其他文件。 用户可以通过易用的标准 UI&#xff0c;以统一方式在所有应用和提供程序中浏…...

Antdesign 4中让分页组件居中显示的方法

在Ant Design 4中分页组件默认是最右边显示的&#xff0c;而这个没有设置位置的属性的 解决办法&#xff1a; 在pagination的属性中增加&#xff1a; style: {textAlign: "center"} 在Ant Design 5中可以让pagination使用align: center来实现分页组件居中...

【笔记】ubuntu 20.04 + mongodb 4.4.14定时增量备份脚本

环境 ubuntu 20.04mongodb 4.4.14还没实际使用&#xff08;20230922&#xff09;后续到10月底如果有问题会修改 原理 只会在有新增数据时生成新的备份日期目录备份恢复时&#xff0c;如果恢复的数据库未删除&#xff0c;则会覆盖数据 准备 准备一个文件夹&#xff0c;用于…...

商丘柘城做网站/北京培训学校

在Eclipse上创建Web项目&#xff0c;默认会产生一个WebRootWEB-INFlib目录&#xff0c;jar包复制到该目录后会自动加载到Web App Libraries库中&#xff0c;效果如下&#xff1a;而如果创建普通的Java项目&#xff0c;一般需要自己创建一个lib目录&#xff0c;再将jar包复制到该…...

网址大全12345/seo优化行业

mysql调优实战如何优化查询效率优化查询效率的方式----建立索引索引的优缺点索引的分类---1,普通索引2,唯一索引3,单列索引4,组合索引5,全文索引6,空间索引索引的选择---创建索引的方式----普通索引与唯一索引之间的区别---多列索引---组合索引---全文索引----空间索引---查看表…...

阜宁网站开发/夸克搜索引擎入口

通常在项目中需要定时的去处理相关任务&#xff0c;这时spring管理容器的定时任务就显得方便的多了&#xff0c;下面是自己整理的两种配置方法&#xff1a; 一.使用quartz配置&#xff1a; ①写好需要执行任务的java类 eg&#xff1a; public class TestSchedueTask { pr…...

珠海市网站建设的公司/制作网站代码

距离2018年高考还有不到一个月的时间了&#xff0c;很多人在准备最后冲刺的同时&#xff0c;也在关心高考成绩。2018各地区高考成绩排名查询,高考各高中成绩喜报榜单尚未公布&#xff0c;下面是往年各地区高考成绩排名查询,高考各高中成绩喜报榜单&#xff0c;想要了解同学可以…...

餐饮门户网站 方案怎么做/网站排名怎么优化

上一篇讨论了链表的反转问题&#xff0c;这一篇讨论链表排序的问题 1. 排序两个有序链表 比较简单&#xff0c;属于归并排序&#xff0c;不再赘述 时间复杂度O(n)&#xff0c; 空间复杂度O(1) 1 ListNode *mergeList( ListNode *list1, ListNode *list2 ) {2 if(!list1 || …...

政府网站规范化建设/教育培训网页设计

thinkphp5多文件上传如何实现 一、总结 一句话总结&#xff1a;官方文档&#xff0c;测试一下&#xff0c;一定要测试&#xff0c;打印中间变量&#xff0c;就知道每句话是什么意思&#xff0c;一定要测试一下。又简单有快。 测试一下&#xff0c;你就能确定中间变量和你的是不…...