原理
通过一个数组收集中间件,然后通过算法让其依次执行,平常所写的业务代码被收集起来,交给框架去最优化运行
命名空间
1 2 3 4 5 6 7 8 9
| let app = { stacks: []; }; app.listen = function (...args) { const server = http.createServer(app.callback); return server.listen(...args); }; module.exports = app;
|
实例收集
通过app.use收集要使用的中间件
1 2 3 4 5 6
| app.use = function(fn) { if(typeof fn === "function"){ throw('middleware must be a function') } app.stacks.push(fn); }
|
算法与运行时
数组的链式调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| app.callback = function(req, res) { dispatch(req, res, app.stacks); } function dispatch(req, res, stack) { let next = function (err) { if (err) { return handleError(err, req, res, stack); } let middleware = stack.shift(); if (middleware) { try { middleware(req, res, next); } catch (err) { next(err); } } }; next(); };
|
中间件
中间件是一个函数,function(req, res, next),req是IncomingMessage对象,res是ServerResponse对象,next函数调用下一个中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const query = function query(options) { var opts = merge({}, options); var queryparse = qs.parse; if (typeof options === "function") { queryparse = options; opts = undefined; } return function query(req, res, next) { if (!req.query) { var val = url.parse(req.url).query; req.query = queryparse(val, opts); } next(); }; }; app.use(query());
|
req 和 res 对象的增强
node 本身的 http 模块不能很好地适应业务需求,需要对其改造
1 2 3 4 5 6 7
| let req = Object.create(null); let res = Object.create(null); app.request = req; app.response = res;
|
mvc模式
模板引擎
1 2 3 4 5 6
| let tpl = str.replace(/<%=([\s\S]+?)%>/g, function (match, code) { return `${code}`; }) res.render = function(viewName, data) {};
|