未加星标

精简版 koa 简单实现

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二03 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏

首先我们先简单封装一个模块 Application 保证服务的正常运行;

初始化一个项目 $ npm init -y ... 复制代码 创建文件 application.js 并并编写如下代码; const http = require('http'); class Application{ // 初始化 constructor(){ this.callback = () => {} } // 设置回调函数 use(callback){ this.callback = callback; } // listen 创建服务并对服务进行监听 listen(...args){ const server = http.createServer((req, res) => { this.callback(req, res); }); server.listen(...args); } } module.exports = Application; 复制代码 创建 server.js 文件,调用 Application 模块起一个服务: const Application = require('./application.js'); const app = new Application(); app.use((req, res) => { res.writeHead(200); res.end('hello world'); }); app.listen(3000, () => { console.log('监听端口:3000'); }); 复制代码 二、 Application 模块挂载 context

首先我们假设我们的 context 是这么一个数据结构:

context 中挂载了 request response req res, 同时还有抽离的额外属性 url body request 中挂载了 req, 同时还有抽离的额外属性 url response 中挂载了 res, 同时还有抽离的额外属性 body context: { url: String, body: String, request: { url: String, req: Object }, response: { body: String, res: Object }, req: Object, res: Object } 复制代码

改写 Application

设计 context request response 原型数据结构; 将 context request response 原型数据结构挂载到 Application 编写函数创建 context 改写回调函数的调用方式; const http = require('http'); // [1]构建数据结构(作为原型使用) const request = { // 因为后期 request 将会挂载上 req 所以存在 this.req get url(){ return this.req.url; } }; const response = { get body(){ return this._body; }, set body(val){ this._body = val; } }; const context = { // 因为后期 context 将会挂载上 request response 所以存在 this.request 和 this.response get url(){ return this.request.url; }, get body(){ return this.response.body; }, set body(val){ this.response.body = val; } } class Application{ constructor(){ this.callback = () => {}, // [2]将原型挂载到 Application this.context = context; this.request = request; this.response = response; } use(callback){ this.callback = callback; } // [3]创建 context 函数,挂载上 request response req res createCtx(req, res){ const ctx = Object.create(this.context); ctx.request = Object.create(this.request); ctx.response = Object.create(this.response); ctx.req = ctx.request = req; ctx.res = ctx.response = res; return ctx; } listen(...args){ const server = http.createServer((req, res) => { // [4]创建 context, 并进行简单修改 const ctx = this.createCtx(req, res); this.callback(ctx); ctx.res.end(ctx.body); }); server.listen(...args); } } module.exports = Application; 复制代码

修改 server.js 中 Application 的引用

const Application = require('./application.js'); const app = new Application(); app.use( ctx => { ctx.body = 'hello world' }); app.listen(3000, () => { console.log('监听端口:3000'); }); 复制代码 三、 中间件的实现 3.1 洋葱模型实现 // 场景模拟 // 异步 promise 模拟 const delay = async () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, 2000); }); } // 中间间模拟 const fn1 = async (ctx, next) => { console.log(1); await next(); console.log(2); } const fn2 = async (ctx, next) => { console.log(3); await delay(); await next(); console.log(4); } const fn3 = async (ctx, next) => { console.log(5); } const middlewares = [fn1, fn2, fn3]; // compose 实现洋葱模型 const compose = (middlewares, ctx) => { const dispatch = (i) => { let fn = middlewares[i]; if(!fn){ return Promise.resolve() } return Promise.resolve(fn(ctx, () => { return dispatch(i+1); })); } return dispatch(0); } compose(middlewares, 1); 复制代码 3.2 compose 函数在 Application 模块中的使用: const http = require('http'); const request = { get url(){ return this.req.url; } }; const response = { get body(){ return this._body; }, set body(val){ this._body = val; } }; const context = { get url(){ return this.request.url; }, get body(){ return this.response.body; }, set body(val){ this.response.body = val; } } class Application{ constructor(){ this.context = context; this.request = request; this.response = response; // 初始化中间件数组 this.middlewares = []; } // 通过push的方式进行添加中间件 use(middleware){ this.middlewares.push(middleware); } createCtx(req, res){ const ctx = Object.create(this.context); ctx.request = Object.create(this.request); ctx.response = Object.create(this.response); ctx.req = ctx.request = req; ctx.res = ctx.response = res; return ctx; } // compose 函数 compose(middlewares, ctx){ const dispatch = (i) => { const fn = middlewares[i]; if(!fn){ return Promise.resolve(); }else{ return Promise.resolve(fn(ctx, () => { dispatch(i +1 ); })); } } return dispatch(0); } listen(...args){ // 改用 async await 并调用compose const server = http.createServer(async (req, res) => { const ctx = this.createCtx(req, res); await this.compose(this.middlewares, ctx); ctx.res.end(ctx.body); }); server.listen(...args); } } module.exports = Application; 复制代码

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

代码区博客精选文章
分页:12
转载请注明
本文标题:精简版 koa 简单实现
本站链接:https://www.codesec.net/view/620928.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(52)