温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Node.js中怎么实现一个express框架

发布时间:2021-07-20 16:31:57 来源:亿速云 阅读:155 作者:Leah 栏目:web开发

本篇文章给大家分享的是有关Node.js中怎么实现一个express框架,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

express的基本用法

const express = require("express");  const app = express();  app.get("/test", (req, res, next) => {    console.log("*1");  //   res.end("2");    next();  });  app.get("/test", (req, res, next) => {    console.log("*2");    res.end("2");  });  app.listen(8888, (err) => {    !err && console.log("监听成功");  });
  •  当我访问localhost:8888/test时候,返回了:2,服务端打印了 

*1  *2
  •  从上面可以看到什么?

    •  express默认引入调用后返回一个app对象

    •  app.listen 会启动进程监听端口

    •  每次收到请求,对应的url和method会触发相应挂载在app上对应的回调函数

    •  调用 next 方法,会触发下一个

一起来实现一个简单的express框架

  •  定义属于我们的express文件入口,这里使用class来实现 

class express {  }  module.exports = express;
  •  需要的原生模块http,创建进程监听端口 

const { createServer } = require("http");
  •  给 class 定义 listen 方法,监听端口 

class express {    listen(...args) {      createServer(cb).listen(...args);    }  }
  •  这样就可以通过调用 class 的 listen 去调用 http 模块的 listen 了,这里的cb我们可以先不管,你要知道每次接受到请求,必然会调用 cb 函数,这个是 createServer 原生模块帮我们封装好的

实现接收到请求触发

  •  实现app.get app.post等方法

    •  目前我们接受到响应,就会触发 cb 这个回调函数,那我们打印下,看看是什么参数? 

class express {    cb() {      return (req, res) => {        console.log(res, res, "开始行动");      };    }    listen(...args) {      createServer(this.cb()).listen(...args);    }  }
  •  发现此时的 req 和 res 正是我们想要的可读流和可写流.

  •  开始编写 get 和 post 方法

    •  这里注意,有路由是'/'的,这种是不管任何路由都会触发一次 

constructor() {      this.routers = {        get: [],        post: [],      };    }    get(path, handle) {      this.routers.get.push({        path,        handle,      });    }    post(path, handle) {      this.routers.post.push({        path,        handle,      });    }
  •  初始化时候定义 get、post 的数组储存对应的 path 和 handle.

  •  需要触发路由回调的时候,首先要找到对应的请求方式下对应的 url 的 handle 方法,然后触发回调.

  •  如何找到对应请求方式下的 url 对应的 handle 方法? 在接到请求时候就要遍历一次

    •  这里要考虑匹配多个路由,意味着,我们可能遇到像最开始一样,有两个 get 方式的 test 路由 

cb() {    return (req, res) => {      const method = req.method.toLowerCase();      console.log(this.routers[method], ",method");      const url = req.url;      this.routers[method].forEach((item) => {        item.path === url && item.handle(req, res);      });    };  }  listen(...args) {    createServer(this.cb()).listen(...args);  }
  •  上面根据 method 找到对应的数组,遍历找到请求的路由,触发回调,此时已经能正常返回数据了 

[ { method: 'get', path: '/test', handle: [Function] } ] ,method
  •  此时最简单的express已经完成了,但是我们好像忘了最重要的中间件

完成最重要的中间件功能

  •  首先要知道,express中间件分两种,一种带路由的,那就是根据路由决定是否触发

  •  另外一种就是不带路由的,像静态资源这种. 是用户访问任何路由都要触发一次的

  •  那我们需要一个 all 数组储存这种任意路由都需要匹配触发的 

constructor() {     this.routers = {       get: [],       post: [],       all: [],     };   }
  •  之前的直接通过 push 方式是太粗暴.如果用户需要中间件功能,不传路由,那就要做特殊处理,这里通过一个中间函数处理下

  •  改造get、post方法,定义handleAddRouter方法 

handleAddRouter(path, handle) {     let router = {};     if (typeof path === "string") {       router = {         path,         handle,       };     } else {       router = {         path: "/",         handle: path,      };     }     return router;   }   get(path, handle) {     const router = this.handleAddRouter(path, handle);     this.routers.get.push(router);   }   post(path, handle) {     const router = this.handleAddRouter(path, handle);     this.routers.post.push(router);   }   use(path, handle) {     const router = this.handleAddRouter(path, handle);     this.routers.all.push(router);   }
  •  每次添加之前,先触发一次handleAddRouter,如果是 path 为空的中间件,直接传入函数的,那么 path 帮它设置成'/'

  •  我们还遗留了一个点,next的实现,因为我们现在加了all这个数组后,意味着可能有多个中间件,那么可能一次请求打过来,就要触发多个路由

这里要注意,promise.then 源码实现和 express 的 next、以及 koa 的洋葱圈、redux 的中间件实现,有着一丁点相似,当你能真的领悟前后端框架源码时候,发现大都相似

  •  阅读我的文章,足以击破所有前后端源码.而且可以手写出来, 我们只学最核心的,抓重点学习,野蛮生长!

实现next

  •  思路:

    •  首先要找到所有匹配的路由

    •  然后逐个执行(看 next 的调用)

  •  定义search方法,找到所有匹配的路由 

search(method, url) {      const matchedList = [];      [...this.routers[method], ...this.routers.all].forEach((item) => {        item.path === url && matchedList.push(item.handle);      });      return matchedList;    }    cb() {      return (req, res) => {        const method = req.method.toLowerCase();        const url = req.url;        const matchedList = this.search(method, url);      };    }
  •  matchedList就是我们想要找到的所有路由

  •  为了完成next,我们要将req ,res , matchedList存入闭包中,定义handle方法 

handle(req, res, matchedList) {     const next = () => {       const midlleware = matchedList.shift();       if (midlleware) {         midlleware(req, res, next);       }     };     next();   }   cb() {     return (req, res) => {       const method = req.method.toLowerCase();       const url = req.url;       const matchedList = this.search(method, url);       this.handle(req, res, matchedList);     };   }
  •  这样我们就完成了next方法,只要手动调用 next 就会调用下一个匹配到的路由回调函数

  •  不到一百行代码,就完成了这个简单的express框架

以上就是Node.js中怎么实现一个express框架,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI