手写koa2

368 阅读1分钟

​一、koa2核心设计

  1. 封装node http server,创造Koa类构造函数

  2. 构造request、response、及context对象

  3. 中间件机制实现

二、koa2核心代码实现

1、主文件koa.js

const http = require('http');
const context = require('./context');
const request = require('./request');
const response = require('./response');​
class Koa {  
    constructor() {    
        this.middlewares = [];  
    }  
    listen(...args) {    
        http.createServer(async (req, res) => {      
            // 创建上下文对象      
            const ctx = this.createContext(req, res);      
            // 将middlewares合并成一个      
            const fn = this.compose(this.middlewares);      
            await fn(ctx);      
            // 给用户返回数据      
            res.end(ctx.body);    
        }).listen(...args);  
    }  
    use(mid) {    
        this.middlewares.push(mid);  
    }  
    createContext(req, res) {    
        const ctx = Object.create(context);    
        ctx.request = Object.create(request);    
        ctx.response = Object.create(response);    
        ctx.req = ctx.request.req = req;    
        ctx.res = ctx.response.res = res;    
        return ctx;    
    }  
    compose(middlewares) { // 中间件机制实现    
        return function(ctx) {      
            return dispatch(0); // 执行第0个      
            function dispatch(i) {        
                let fn = middlewares[i];        
                if (!fn) {          
                    return Promise.resolve();        
                }        
                return Promise.resolve(          
                    fn(ctx, function next() {            
                        // promise完成后,再执行下一个            
                        return dispatch(i + 1);                    
                    });        
                )         
            }    
        }  
    }
}

2、封装request:request.js

module.exports = {  
    get url() {    
        return this.req.url;  
    }
}

3、封装response:response.js

module.exports = {  
    get body() {    
        return this._body;  
    }  
    set body(val) {    
        this._body = val;    
    }
}

4、封装context:context.js

module.exports = {  
    get url() {    
        return this.request.url;  
    }  
    get body() {    
        return this.response.body;  
    }  
    set body(val) {    
        this.response.body = val;  
    }
}

以上为koa2的核心实现,仅作为学习和理解核心原理用,实际中的koa2有更多详尽的实现,具体查阅https://github.com/koajs/koa/tree/master/lib。


参考资料

  1. https://study.miaov.com/study/show/chapter/639


微信公众号“前端那些事儿”