Express、Koa2的初步认识以及中间件对比
此文仅仅对koa作了解用,暂时还不打算深入学习,目前还是以学习前端为主,学了generator、async这些就多了解了点。
个人觉得,要学koa就必须把ES6学好,主要差别也就在这了。
了解express、koa、koa2的升级路程
白昔月 谈我眼中的express、koa和koa2(必看!)
express用Application、Request、Response、Router四个主要模块,模拟了一个完整的web服务器功能。
koa中也包含4个主要模块,Application、Request、Response、Context。此时,router已经被排除在内核之外了。其实,koa只是一个“中间架”,几乎所有的功能都需要由第三方中间件来协同完成。
目前的koa官方github已经全面的使用koa2版本的代码了,换句话说,koa和koa2现在只是版本上的区别了,koa是老版本,koa2用新的版本号。
一句非常重要的提示
Koa requires node v7.6.0 or higher for ES2015 and async function support.
。
意思是说,koa需要至少node v7.6.0版本和ES2015(es6+async)才能使用。这个提示,也是非常重要的一句话,从这个版本开始,我们可以抛弃Bable快乐的使用async等新的语法了。(当然,nodev7.6还是不能完全抛弃babel,因为到目前为止,node都还没有实现对import和export的支持。Babel 自带了一组 ES2015 语法转化器。这些转化器能让你现在就使用最新的 JavaScript 语法,而不用等待浏览器和node提供支持。)
中间件对比
Koa2中间件
koa2的中间件是通过 async await 实现的,中间件执行顺序是“洋葱圈”模型。
中间件之间通过next函数联系,当一个中间件调用 next() 后,会将控制权交给下一个中间件, 直到下一个中间件不再执行 next() 后, 将会沿路折返,将控制权依次交换给前一个中间件。
const Koa = require('koa');
const app = new Koa();
const one = async (ctx, next) => {
console.log('>> 1 start');
await next();
console.log('<< 1 end');
}
const two = async (ctx, next) => {
console.log('>> 2 start');
await next();
console.log('<< 2 end');
}
const three = async (ctx, next) => {
console.log('>> 3 start');
await next();
console.log('<< 3 end');
}
app.use(one);
app.use(two);
app.use(three);
app.listen(3000);
/*
输出
>> 1 start
>> 2 start
>> 3 start
<< 3 end
<< 2 end
<< 1 end
*/
express中间件
与 koa2 中间件不同的是,express中间件一个接一个的顺序执行, 通常会将 response 响应写在最后一个中间件中。
const express = require('express')
const app = express()
const one = (re1, res, next) => {
console.log('>> 1 start');
setTimeout(() => {
next()
}, 0)
console.log('<< 1 end');
}
const two = (re1, res, next) => {
console.log('>> 2 start');
setTimeout(() => {
next()
}, 0)
console.log('<< 2 end');
}
const three = (re1, res, next) => {
console.log('>> 3 start');
setTimeout(() => {
next()
}, 0)
console.log('<< 3 end');
}
app.use(one);
app.use(two);
app.use(three);
app.listen(3000)
/*
输出:
>> 1 start
<< 1 end
>> 2 start
<< 2 end
>> 3 start
<< 3 end
*/
因为上面各个中间件中的 next() 是异步执行的,所以 打印结果是线行输出的。
如果取消上面next()的异步执行,直接按如下方式:
/*
输出:
>> 1 start
>> 2 start
>> 3 start
<< 3 end
<< 2 end
<< 1 end
*/
可见,express 的中间件也可以形成“洋葱圈”模型,但是一般在express中不会这么做,因为 express 的 response 一般在最后一个中间件,所以其它中间件 next() 后的代码影响不到最终结果。