const {createServer} = require('http'); const context = require('./my-context'); const request = require('./my-request'); const response = require('./my-response'); module.exports = class Application { constructor() { this.middleware = []; // Object.create(target) 以target对象为原型, 创建新对象, 新对象原型有target对象的属性和方法 this.context = Object.create(context); this.request = Object.create(request); this.response = Object.create(response); } use(fn) { this.middleware.push(fn); } listen(...args) { // 使用nodejs的http模块监听端口号 const server = createServer(this.callback()); server.listen(...args); } callback() { const fn = compose(this.middleware); const handleRequest = (req, res) => { // 创建context const ctx = this.createContext(req, res); const handleResponse = () => respond(ctx); fn(ctx).then(handleResponse); } return handleRequest; } // 创建context 上下文对象的方法 createContext(req, res) { /* 凡是req/res,就是node原生对象 凡是request/response,就是自定义对象 这是实现互相挂载引用,从而在任意对象上都能获取其他对象的方法 */ const context = Object.create(this.context); const request = context.request = Object.create(this.request); const response = context.response = Object.create(this.response); context.app = request.app = response.app = this; context.req = request.req = response.req = req; context.res = request.res = response.res = res; request.ctx = response.ctx = context; request.response = response; response.request = request; return context; } } // 将原来使用req,res的地方改用ctx function compose(middleware) { return (ctx) => { return dispatch(0); function dispatch(i) { let fn = middleware[i]; if (!fn) return Promise.resolve(); return Promise.resolve(fn(ctx, dispatch.bind(null, i + 1))); } } } function respond(ctx) { let body = ctx.body; const res = ctx.res; if (typeof body === 'object') { body = JSON.stringify(body); res.end(body); } else { res.end(body); } }
修改入口文件 index.js 代码
// 引入自定义模块 const MyKoa = require('./js/my-application'); // 创建实例对象 const app = new MyKoa(); // 使用中间件 app.use((ctx, next) => { console.log('中间件函数执行了~~~111'); next(); }) app.use((ctx, next) => { console.log('中间件函数执行了~~~222'); // 获取请求头参数 console.log(ctx.headers); // 获取查询字符串参数 console.log(ctx.query); // 设置响应头信息 ctx.set('content-type', 'text/html;charset=utf-8'); // 设置响应内容,由框架负责返回响应~ ctx.body = '<h1>hello myKoa</h1>'; }) // 监听端口号 app.listen(3000, err => { if (!err) console.log('服务器启动成功了'); else console.log(err); })
到这里已经写完了 Koa 主要代码,有一句古话 - 看万遍代码不如写上一遍。 还等什么,赶紧写上一遍吧~当你能够写出来,再去阅读源码,你会发现源码如此简单~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章: