# learnKoaHard **Repository Path**: mrstack/learnKoaHard ## Basic Information - **Project Name**: learnKoaHard - **Description**: No description available - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-05-22 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [基于 阮老师 koa-demos](https://github.com/ruanyf/koa-demos) ## Demo9: MiddleWare之next() 的执行顺序  ## 说明 koa 是从第一个中间件开始执行, 遇到 next() 进入下一个中间件, 一直执行到最后一个中间件,然后再逆序出来。 ```javascript // src/09.js const Koa = require('koa'); const app = new Koa(); const one = (ctx, next) => { console.log('>> one'); next(); console.log('<< one'); } const two = (ctx, next) => { console.log('<< two'); next(); console.log('<< two'); } const three = (ctx, next) => { console.log('>> three'); next(); console.log('<< three'); } app.use(one); app.use(two); app.use(three); app.listen(3000); ``` Run the demo and the output: ```bash node 09.js >> one >> two >> three << three << two << one ``` ## Demo10: async middleware 如果要在中间件中使用异步操作, 那必须使用异步中间件, 此处使用了 `fs.promised` 库, 定义一个 async function ```javascript // src/10.jss 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.readFile()` 是一个异步操作, 所以必须在前面加上 `await`, 然后把它放在异步函数中。 ## Demo11: 合成复杂组件 通过 `koa-compose` 将 联排 app.use() 放在一个数组。 ```javascript // Demo11.js const Koa = require('koa'); const compose = require('koa-compose'); 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 = 'Hello World'; }; const middlewares = compose([logger, main]); app.use(middlewares); app.listen(3000); ``` ## Demo18 定制error event 时机: 当 err listener 不能在所有情况下奏效时,可以特别定制 ```javascript const Koa = require('koa'); const app = new Koa(); const handler = async (ctx, next) => { try{ await next(); } catch (err) { ctx.response.status = err.statusCode || err.status || 500; ctx.response.type = 'html'; ctx.response.body = '
Someting wrong, contact admin.
'; ctx.app.emit('error', err, ctx); } }; const main = ctx => { ctx.throw(500); }; app.on('error', function (err) { console.log('logging error', err.message); console.log(err); }); app.use(handler); app.use(main); app.listen(3000); ``` ## Demo20: form `koa-body` 包用作解析 POST 请求。 ```javascript const Koa = require('koa'); const koaBody = require('koa-body'); const app = new Koa(); const main = async function(ctx) { const body = ctx.request.body; if (!body.name) ctx.throw(400, '.name required'); ctx.body = { name: body.name }; }; app.use(koaBody()); app.use(main); app.listen(3000) ``` curl POST ```bash curl -X POST "name=David" 127.0.0.1:3000 ``` Output: ```bash {"name": "David"} ``` ## Demo21 upload ```javascript const os = require('os'); const path = require('path'); const Koa = require('koa'); const fs = require('fs'); const koaBody = require('koa-body'); const app = new Koa(); const main = async function(ctx) { const tmpdir = os.tmpdir(); const filePaths = []; const files = ctx.request.body.files || {}; for (let key in files) { const file = files[key]; const filePath = path.join(tmpdir, file.name); const reader = fs.createReadStream(file.path); const writer = fs.createWriteStream(filePath); reader.pipe(writer); filePaths.push(filePath); } ctx.body = filePaths; }; app.use(koaBody({multipart: true})); app.use(main); app.listen(3000); ``` 使用 curl 上传图片 ```bash curl http://localhost:3000 -F "image=@Selection_001.png" ``` Output: ```bash ["/tmp/Selection_001.png"] ```