深入解析koa之中间件流程控制(2)

怎么样?是不是有一点koa中间件写法的感觉了呢?但是目前,我们还是一步一步手动的在执行我们这个洋葱模型,能否写一个函数,自动的来执行我们这个模型呢?

3. 让洋葱模型自动跑起来:一个run函数的编写

上面例子中,最后的代码我们可以看出一个规律,基本就是外层的generator调用next方法把控制权交给内层,内层再继续调用next把方法交给更里面的一层。整个流程可以用一个函数嵌套的写法写出来。话不多说,直接上代码:

function run(gen) { var g; if (typeof gen.next === 'function') { g = gen; } else { g = gen(); } function next() { var tmp = g.next(); //如果tmp.done为true,那么证明generator执行结束,返回。 if (tmp.done) { return; } else if (typeof g.next === 'function') { run(tmp.value); next(); } } next(); } function compose(middlewares) { return function(next) { var i = middlewares.length; var next = function*() {}(); while (i--) { next = middlewares[i].call(this, next); } return next; } } var gen1 = function*(next) { console.log('begin!'); yield next; console.log('end!'); } var gen2 = function*(next) { console.log('begin 2'); yield next; console.log('end 2'); } var gen3 = function*(next) { console.log('this is another function!'); } var bundle = compose([gen1, gen2, gen3]); run(bundle);

run函数接受一个generator,其内部执行其实就是我们上一个例子的精简,使用递归的方法执行。运行这个例子,可以看到结果和我们上一个例子相同。

到此为止,我们就基本讲清楚了koa中的中间件洋葱模型是如何自动执行的。事实上,koa中使用的co函数,一部分功能就是实现我们这里编写的run函数的功能。

值得注意的是,这篇文章只注重分析中间件执行流程的实现,暂时并没有考虑异步回调同步化原理。下一篇文章中,我将带大家继续探析koa中异步回调同步化写法的机理。

这篇文章的代码可以在github上面找到:https://github.com/mly-zju/async-js-demo,其中process_control.js文件就是本篇的事例源码。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/75d2ae1613ebff595dd7252ab23d3bfd.html