儘管koa2中已經被async/await代替。但我仍是想自個兒着寫一個koa1中的generator。javascript
一,java
寫這個以前,先寫一個能夠現實,express中next用法的函數:node
var event=require('events').EventEmitter; class App extends event{ constructor(){ super(); this.arr=[],this.i=0; this.on('next',data=>{ let node=this.arr[++this.i]; if (!node) return ; node(this.next); }) } next(){ this.emit('next'); } use(v){ this.arr.push(v); } end(){ this.arr[this.i](this.next.bind(this)); } }
使用:express
var myApp=new App(); myApp.use(next=>{ console.log('step1'); next(); }) myApp.use(next=>{ console.log('step2'); }) myApp.end();
二, 框架
很成功。好了。下面寫koa裏的實現,就直接寫function 了。這樣寫得快些 - -!。。:koa
function App(){ let arr=[],i=0; let self=this; let next=function(){ if(!arr[++i]) return ; self.end(); }; this.use=function(fn){ arr.push(fn); } this.end=function(){ let g=arr[i](next); let run=function(){ //run函數執行這個generator; let result=g.next(); if(result.done) return; result.value();
run(); } g?run():0; } }
使用:async
var a=new App(); a.use(function* (next){ console.log('a1'); yield next; }) a.use(function* (next){ console.log('b1'); yield next; console.log('b2'); yield next; }) a.use(function* (next){ console.log('c1'); yield next; }) a.use(function(){ console.log('c2') }) a.use(function(){ console.log('c3') }) a.end();
返回結果:函數
a1;ui
b1;this
c1;
c2;
b2;
c3;
好的這樣大體框架就成功了。其他的能夠慢慢進化。。