60行代码写一个超简陋的koa
发布: 2021-05-12 11:14:48标签: nodeJs
一个很简陋的koa代码,可以很轻松的了解koa的工作流程
app.js代码
01const http = require('http')02const { Stream } = require('stream')03const qs = require('querystring')0405const app = {06 middleware: [],07 use(fn) {08 this.middleware.push(fn)09 },10 listen(port = 3000) {11 const server = http.createServer(this.callback.bind(this))12 return server.listen(port)13 },14 async callback(req, res) {15 console.log('start')16 const fn = compose(this.middleware)17 // 这里有很多代理的方法18 const ctx = {19 request: req,20 response: res,21 req,22 res,23 get query() {24 return { ...qs.parse(req.url.split('?')[1] || '') }25 },26 }27 await fn(ctx)28 .then(() => {29 const { body } = ctx30 if (!body) return res.end('null')31 if (Buffer.isBuffer(body)) return res.end(body)32 if (typeof body === 'string') return res.end(body)33 if (body instanceof Stream) return body.pipe(res)34 return res.end(JSON.stringify(body))35 })36 .catch((error) => {37 res.end(error.toString())38 })39 console.log('end')40 },41}4243function compose(middleware = []) {44 let index = -14546 return (ctx, next) => {47 return dispatch(0)48 function dispatch(i) {49 if (i <= index) return Promise.reject(new Error('next() called multile times'))50 index = i51 let fn = middleware[i]52 if (i === middleware.length) fn = next53 if (!fn) return Promise.resolve()54 try {55 return Promise.resolve(fn(ctx, dispatch.bind(null, i + 1)))56 } catch (err) {57 return Promise.reject(err)58 }59 }60 }61}6263module.exports = app64
复制代码test.js 代码
01// const fs = require('fs')02const app = require('./app')0304app.use(async function test1(ctx, next) {05 console.log(1)06 console.log('query', ctx.query)07 await next()08 console.log(6)09})10app.use(async function test2(ctx, next) {11 console.log(2)12 await next()13 console.log(5)14})15app.use(async function test3(ctx, next) {16 await next()17 // ctx.body = fs.createReadStream('asset/a.jpg')18 console.log(4)19})2021app.listen(8000)2223console.log('http://localhost:8000')24
复制代码