'use strict'
module.exports = compose
function compose (middleware) {
// 类型判断 middleware必需是一个函数数组
if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!');
for (const fn of middleware) {
if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!');
}
// 返回一个函数,接受context和next参数,koa在调用koa-compose时只传入context,所以此处next为undefined
return function (context, next) {
// last called middleware #
// 初始化index
let index = -1;
// 从第一个中间件开始执行
return dispatch(0);
function dispatch (i) {
// 在一个中间件出现两次next函数时,抛出异常
if (i <= index) return Promise.reject(new Error('next() called multiple times'));
// 设置index,作用是判断在同一个中间件中是否调用多次next函数
index = i;
// 中间件函数
let fn = middleware[i]
// 跑完所有中间件时,fn=next,即fn=undefined,可以理解为终止条件
if (i === middleware.length) fn = next
// fn为空时,返回一个空值的promise对象
if (!fn) return Promise.resolve();
try {
// 返回一个定值的promise对象,值为下一个中间件的返回值
// 这里时最核心的逻辑,递归调用下一个中间件,并将返回值返回给上一个中间件
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err)
}
}
}
}
module.exports = function(options) {
// 配置处理
return async (ctx, next) => {
// 中间件逻辑...
}
}
node开启http服务
var http = require ('http');
http.createServer(function(request, response){}).listen(3000);
console.log('server has started...');
koa开启http服务
var koa = require('koa');
var app = koa();
app.use(function(){
});
app.listen(3000,function(){
})
express中间件
/**
* 仿照express实现中间件的功能
*
* Created by BadWaka on 2017/3/6.
*/
var http = require('http');
/**
* 仿express实现中间件机制
*
* @return {app}
*/
function express() {
var funcs = []; // 待执行的函数数组
var app = function (req, res) {
var i = 0;
function next() {
var task = funcs[i++]; // 取出函数数组里的下一个函数
if (!task) { // 如果函数不存在,return
return;
}
task(req, res, next); // 否则,执行下一个函数
}
next();
}
/**
* use方法就是把函数添加到函数数组中
* @param task
*/
app.use = function (task) {
funcs.push(task);
}
return app; // 返回实例
}
// 下面是测试case
var app = express();
http.createServer(app).listen('3000', function () {
console.log('listening 3000....');
});
function middlewareA(req, res, next) {
console.log('middlewareA before next()');
next();
console.log('middlewareA after next()');
}
function middlewareB(req, res, next) {
console.log('middlewareB before next()');
next();
console.log('middlewareB after next()');
}
function middlewareC(req, res, next) {
console.log('middlewareC before next()');
next();
console.log('middlewareC after next()');
}
app.use(middlewareA);
app.use(middlewareB);
app.use(middlewareC);
koa与express