同步中间件很容易理解,如以下代码:
1 const Router = require('koa-router') 2 , koa = new Router({ prefix: '/koa' }) 3 4 , fs = require('fs') 5 ; 6 /* 中间件执行顺序 与异步中间件 */ 7 const one = (ctx, next) => { 8 console.log('>> one'); 9 next(); 10 console.log('<< one'); 11 }; 12 13 const two = (ctx, next) => { 14 console.log('>> two'); 15 next(); 16 console.log('<< two'); 17 }; 18 19 const three = (ctx, next) => { 20 console.log('>> three'); 21 next(); 22 console.log('<< three'); 23 }; 24 25 koa['get']('/middleStack', one, two, three, async (ctx) => { 26 console.log('>> four'); 27 ctx.response.type = 'html'; 28 let aaa = 'aa'; 29 console.log('<< four'); 30 ctx.response.body = aaa; 31 });
以上代码在控制台一次打印:
>> one
>> two
>> three
>> four
<< four
<< three
<< two
<< one
如果将其中一个中间件改为异步中间件:
1 koa['get']('/middleStack', one, two, three, async (ctx) => { 2 console.log('>> four'); 3 ctx.response.type = 'html'; 4 let aaa = await fs.openSync('./public/index.html','r'); 5 console.log('<< four'); 6 ctx.response.body = aaa; 7 });
则控制台打印顺序为:
>> one
>> two
>> three
>> four
<< three
<< two
<< one
<< four
同步中间件并不会等待异步中间件返回结果才继续 next 之后的代码,若将所有的中间件都改为异步中间件:
1 /* 中间件执行顺序 与异步中间件 */ 2 const one = async (ctx, next) => { 3 console.log('>> one'); 4 await next(); 5 console.log('<< one'); 6 }; 7 8 const two = async (ctx, next) => { 9 console.log('>> two'); 10 await next(); 11 console.log('<< two'); 12 }; 13 14 const three = async (ctx, next) => { 15 console.log('>> three'); 16 await next(); 17 console.log('<< three'); 18 }; 19 20 koa['get']('/middleStack', one, two, three, async (ctx) => { 21 console.log('>> four'); 22 ctx.response.type = 'html'; 23 let aaa = await fs.openSync('./public/index.html','r'); 24 console.log('<< four'); 25 ctx.response.body = aaa; 26 });
>> one
>> two
>> three
>> four
<< four
<< three
<< two
<< one
打印顺序又回到所有的中间件为同步中间件的情况。
总结:在 koa 变成中,尽量将所有的中间件都些为异步中间件,使得执行顺序是可控可理解的。