🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 一、中间件 ### 1.1 logger功能 > Koa 的最大特色,也是最重要的一个设计,就是中间件(middleware)。 > Logger:打印日志 ``` const Koa = require('koa') const app = new Koa() const main = ctx => { console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`) ctx.response.body='请求了' } app.use(main) app.listen(3000) # 访问后 1502144902843 GET / ``` ### 1.2 中间件概念 > 上面例子里的Logger功能,可以拆分成一个独立函数 ``` const Koa = require('koa') const app = new Koa() const logger = (ctx,next) => { console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`) next() } const main = ctx => { ctx.response.body='呵呵' } app.use(logger) app.use(main) app.listen(3000) ``` - 以上的logger函数,main函数就是一个中间件middleware,因为它处在http request和response之间,用来实现某种中间功能 - app.use(middleWare) 来使用中间件 - 参数:默认接受2个参数 (ctx,next),ctx为context对象,当执行完中间件的功能后,调用next()将执行权交移给下一个中间件 ### 1.3 中间件栈 >多个中间件会形成一个栈结构(middle stack),以"先进后出"(first-in-last-out)的顺序执行。 > 1. 最外层的中间件首先执行。 2. 调用next函数,把执行权交给下一个中间件。 3. ... 4. 最内层的中间件最后执行。 5. 执行结束后,把执行权交回上一层的中间件。 6. ... 7. 最外层的中间件收回执行权之后,执行next函数后面的代码。 ``` const one = (ctx,next) => { console.log('one->') next() console.log('<-one') } const two = (ctx, next) => { console.log('2->') next() console.log('<-2') } # 执行结果 one-> 2-> <-2 <-one ``` - 如果不调用next(),则不会移交执行权 ### 1.4 异步中间件 > 如果有异步操作(比如读取数据库),中间件就必须写成 async 函数。 ``` //fs.promised模块是对fs模块的扩展,需单独这安装后使用 const fs = require('fs.promised'); const Koa = require('koa'); const app = new Koa() const main = async function(ctx,next){ ctx.response.type='html'; ctx.response.body= await fs.readFile('./template.html','utf8') } app.use(main) app.listen(3000) ``` > **fs.promised模块**: > 原fs模块读取文件后都要用回调函数来处理结果,而fs.promised可以用**promised**来代替回调函数。 ``` # 安装 npm i fs.promised -S # 使用 const fs = require('fs.promised') fs.readFile('./test.json').then(v=>console.log(v),error=>console.log(error)) ``` ### 1.5 中间件的合成 > koa-compose模块可以将多个中间件合成为一个 ``` const Koa = require('koa') const compose = require('koa-compose') const app = new Koa() const logger = function (ctx,next) { console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`) next() } const main = function (ctx,next) { ctx.response.body='这是首页' } const middleWare = compose([logger, main]) app.use(middleWare) app.listen(3000) ```