几十行代码实现简易版koa~
application.js
const http = require("http")
// 洋葱模型 function compose(middleware){ return function(ctx,next){ let index = -1 return dispatch(0) function dispatch(i){ if(i <= index ){ return Promise.reject(new Error("what!!")) } index = i fn =middleware[i] if (i === middleware.length){fn = next } if(!fn){ return Promise.resolve() } try { return Promise.resolve(fn(ctx,dispatch.bind(null,++i))) } catch (error) { return Promise.reject(error) } } } } class Koa { constructor(options){ this.options = options this.middleware = [] } use(fn){ if(typeof fn !== "function"){ throw new Error("not a function") } this.middleware.push(fn) } listen(){ let server = http.createServer(this.callback()) server.listen(...arguments) } callback(){ let fnMiddleWare = compose(this.middleware) let handleRequest = (req,res)=>{ this.handleRequest(fnMiddleWare,req,res) } return handleRequest } handleRequest(fnMiddleWare,req,res){ let ctx = this.createContext(req,res) fnMiddleWare(ctx).then(this.handleResponse).catch(this.handleError) } handleResponse(){} handleError(){} createContext(req,res){ //不会破坏原对象,方便扩展 let ctx = Object.create({}) ctx.req = req; ctx.res =res; return ctx } } module.exports = Koa
使用:
const koa = require("./koa/application") const app = new koa() app.use(async (ctx,next)=>{ ctx.res.write("111") await next() ctx.res.write("333") ctx.res.end() }) app.use(async (ctx,next)=>{ ctx.res.write("222") await next() }) app.listen(3000);