Skip to content

Latest commit

 

History

History
73 lines (62 loc) · 2.6 KB

封装个Koa.md

File metadata and controls

73 lines (62 loc) · 2.6 KB
title date tags categories
封装个Koa
2018-09-13 09:39:37 -0700
Node
Koa
Node

想了解下Koa是怎么个骚操作,之前使用的是Koa2,里面是asyncawait,用起来爽歪歪。不过,asyncawait是ES7里面的东东,还是有必要看一下koa的第一代的,发现里面的中间件是Generator,其实我对这个也不是很理解,ES6里面新增加的,一下子有点难接受,今天就提上日程,看一看怎么搞,自己封装个Koa试试!

想要真正搞懂这个Generator还是比较烦,我自己感觉整个ES6的主要部分应该就是这个Generator了,相知带它怎么回事先要知道Iterator、然后再看Generator,但是想和异步扯上关系你还要看Chunk函数,还要看看co库,当然啦,Promise肯定要知道,所以感觉这也不是个简单的东西,门道多着呢。

不说废话了,上代码吧,封装个MyKoa

class MyKoa extends Object {
	constructor(props) {
    	super(props);

    	// 存储所有的中间件
    	this.middlewares = []
	}

	// 注入中间件
	use (generator) {
    	this.middlewares.push(generator)
	}

	// 执行中间件
	listen () {
    	this._run()
	}

	_run () {
    	const ctx = this;
    	const middlewares = ctx.middlewares;
    	co(function* () {
        	let prev = null
        	let i = middlewares.length
        	//从最后一个中间件到第一个中间件的顺序开始遍历
        	while (i--) {
            	// ctx 作为函数执行时的 this 才能保证多个中间件中数据的共享
            	//prev 将前面一个中间件传递给当前中间件,才使得中间件里面的 next 指向下一个中间件
            	prev = middlewares[i].call(ctx, prev);
        	}
        	//执行第一个中间件
        	yield prev;
    	})
	}
}

然后可以试验下效果:

var app = new MyKoa();
app.use(function *(next){
	this.body = '1';
	yield next;
	this.body += '5';
	console.log(this.body);  // 12345
});
app.use(function *(next){
	this.body += '2';
	yield next;
	this.body += '4';
});
app.use(function *(next){
	this.body += '3';
});
app.listen();

其实Generator和我们的回调处理异步的callback根本没有一点关系,它的本质是‘暂停’,并将执行权转移,我们只是给它穿上了一层又一层的外套,强行让它和异步‘发生关系’。

PS:立个flag,2018年过年之前找个机会,我一定彻彻底底研究次js中的异步!!!