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('执行完了'); });
相关文章推荐
- FTP 字体不识别 svg/woff/woff2字体 404错误
- 利用lavarel查询 orWhere的使用
- 大量数据表的优化方案
- Goodix系列------如何取消原生的屏幕上的三个key(如何在java里获取property)
- hdu1160(最长下降子序列+排序)
- spring boot入门(一)
- java.rmi.server.ExportException: Port already in use: 1099的解决办法
- java 生成22位UUID 改造
- Eclipse 混淆打包
- .NET Core跨平台开发
- jq animate动画 自制slider
- 判断iOS设备是否越狱
- 修改setting的文本框高亮颜色和android系统全局高亮颜色
- POJ 1046 (枚举,类)
- BitTorrent Sync的原理介绍
- 常见的几种读取.properties文件的方式
- js 中 foreach循环(for in)中,最后会多出一个值
- Java中只有按值传递,没有按引用传递
- JProfiler使用入门(一)——准备工作
- nginx 获取远程地址