本系列旨在经由历程对co,koa等库源码的研讨,进而明白generator在异步编程中的严重作用(ps:一切代码请在node –harmony或许iojs环境中运转)
koa中间件的情势
置信用过koa的小伙伴肯定很熟习下面这段代码
var app = require('koa')(),
router = require('koa-router')();
app.use(function *(next){
console.log(1);
yield next;
console.log(5);
});
app.use(function *(next){
console.log(2);
yield next;
console.log(4);
});
app.use(function *(){
console.log(3);
});
app.listen(3000);
当一个要求抵达的时刻,控制台会顺次输出1 2 3 4 5
,这就是koa中壮大的middleware特征,撇开koa自身,我们来扯扯middleware这东西是怎样完成的
yield *iterator
不熟习generator
和iterator
的小伙伴能够先看下阮一峰教师编写的《ES6入门》的generator函数这一节
假定你已熟习了generator和iterator,如今我们来看一段代码
function *m1(){
console.log(1);
yield *m2Iterator;
console.log(3);
}
function *m2(){
console.log(2);
}
var m1Iterator = m1(),
m2Iterator = m2();
m1Iterator.next();//
上面代码运转后,控制台会顺次输出1 2 3
,这是因为在m1
函数内部,yield
背面跟的是一个iterator
。m1Iterator.next()
挪用后,m1
函数最先实行。
当m1
运转到yield *m2Iterator
时,不会停息,而是直接跳进m2
函数实行m2
函数内的代码。
因为m2
函数中没有yield
,因而会一向实行完m2
函数中的代码,并返回至m1
函数中实行yield *m2Iterator
背面的代码。
middleware中间件的雏形
明白了上面的历程后,我们接着看下面这段代码
function *m1(){
console.log(1);
yield *m2();
console.log(5);
}
function *m2(){
console.log(2);
yield *m3();
console.log(4);
}
function *m3(){
console.log(3);
}
m1().next(); //控制台顺次输出1 2 3 4 5
是否是情势跟我们一最先看到的koa
的中间件有点接近了?
compose
compose是koa
里用来完成中间件机制的模块compose
函数最症结的一段代码
while(i--){
next = middleware[i].call(this, next);
}
yield *next;
这段代码把middleware
中传进来的generator
数组逆序掏出并顺次实行,每次实行的时刻把上次generator
实行返回的iterator
看成参数传进去,一切generator
实行完今后,挪用第一个iterator
因而,在generator
中间件函数中,实在yield
背面跟的是个iterator
,即yield *next
下面用一个例子来申明这个历程
function *m1(next){
console.log(1);
yield *next;
console.log(5);
}
function *m2(next){
console.log(2);
yield *next;
console.log(4);
}
function *m3(){
console.log(3);
}
var gen = compose([m1, m2, m3]),
it = gen();
//compose([m1, m2, m3])()能够设想成它做了这么一些事(伪代码):
//1 var it3 = m3();
//2 var it2 = m2(it3);
//3 var it1 = m1(it2);
//4 gen = function(){
// yield *it1;
// }
it.next(); //控制台顺次输出1 2 3 4 5
如今就很像koa
的中间件的写法了。唯一的差别是koa
中运用的是yeild next
而我们这里用的是yield *next
实在在koa
中yeild next
和yeild *next
结果是等价的,这重要得益于co库,我们今后再来好好扯扯这小玩意~