您的位置:首页 > 其它

koa中间件实现分析

2016-05-19 17:34 302 查看
最近团队内部做了一个web app,用koa做服务端,一直对他中间件实现很感兴趣,对他的源码研究之后,写了一份简化版本的中间件实现。代码除了用到ES6的Generator和Promise,没有用到其他三方库,总共不到一百行,希望能帮助大家理解!

'use strict';
var middleware = [];

//向数据库请求数据
var getDataPromise = new Promise(function(resolve,reject){
setTimeout(function(){
resolve({
data:'这就是数据'
});
},1500)
});

/**
* session中间件
* @param next
*/
function* session(next){
console.log(1);
yield next;
console.log(2);
}
middleware.push(session);

/**
* logger中间件
*/

function* logger(next){
console.log(3);
yield next;
console.log(4);
}
middleware.push(logger);

/**
* response中间件
*/
function* response(){
console.log(5);
console.log('请求数据库数据...');
let data = yield getDataPromise;
console.log(data);
console.log(6);
}
middleware.push(response);

/**
* 将中间件的遍历器函数转化为遍历器对象,并且将每一个遍历器对象指定为下一个遍历器对象的参数
* @param next
* @returns {*}
*/
function* toGeneratorObject(next){
if (!next) next = function*(){};

var i = middleware.length;

while (i--) {
next = middleware[i].call(this, next);
}

return yield *next;
}

//第一个中间件的遍历器对象
var firstMiddleWareGenerator = toGeneratorObject();

/**
* 将中间件的遍历器对象包装成一个Promise
* @param gen
* @returns {Promise}
*/
function  wrapPromise(gen){
return new Promise(function(resolve,reject){
function onFullField (res){
var ret = gen.next(res);
next(ret);
}
onFullField();
function next(ret){
var value = null;
if(ret.done){
resolve(ret.value);
return;
}
//假如是promise,不做任何处理
if(typeof ret.value.then == 'function'){
value = ret.value;
}else { //假如不是,就包装成promise实例
value = wrapPromise(ret.value);
}
value.then(onFullField);
}
});
}
wrapPromise(firstMiddleWareGenerator).then(function(){
console.log('执行完了');
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: