写在前面
准备写个koa用一下,顺便记录下遇到的坑
KOA洋葱模型概念
以 next() 为分界线。分为前半部分,后半部分。
执行顺序为 1上 -> 2上 -> 3上 -> 3下 -> 2下 -> 1下
const Koa = require('koa');
const app = new Koa()
// 应用程序对象 中间件
// 发送HTTP KOA 接受HTTP
// 注册 -> 中间件
app.use(async (ctx, next) => {
// ctx => 上下文 约等 this
await next()
// 添加await 保证洋葱模型正常运行
console.log(ctx)
})
app.use(async (ctx, next) => {
const axios = require('axios')
const res = await axios.get('https://home.evente.cn/crm/contacts')
console.log(res)
await next()
})
app.listen(3000)
重点:async await 的使用才能保证洋葱模型正确执行
KOA-router 路由
const Koa = require('koa');
const Router = require('@koa/router');
// 实例化
const app = new Koa();
const router = new Router();
// 编写中间件
router.get('/', (ctx, next) => {
// ctx.router available
ctx.body = {key: 'class'} // return在koa中用法
});
// 注册中间件 use
app
.use(router.routes())
.use(router.allowedMethods());
自动重启服务
当然vscode配合更爽
路由模块自动注册
const requireDirectoyr = require('require-directory')
// 注册某个目录下的所有模块
requireDirectoyr(module, './api', { visit: whenLoadModule })
function whenLoadModule() {
if (obj instanceof Router) {
app.use(obj.routes())
}
}
异常处理
全局异常处理
// (异步编程是 捕捉不到异常的)
function func1 () {
try() {
} catch(err) {
// 因为异步事件 func2 实际return出一个 '' 不会捕捉到异常
console.log(err)
}
}
function func2() {
setTimeOut(() => {
throw new Error('err')
})
}
func1()
// 异常处理 catch推荐写法
async function func() {
try {
await func2() // 当然必须是promise 才能await
} catch (error) {
console.log(error)
}
}
使用中间件来全局监听异常
const catchError = async (ctx, next) => {
try {
await next()
} catch (error) {
ctx.body = '服务器错误'
}
}
module.exports = catchError
// 其他api文件
throw new Error('API ERROR')
动态返回数据
当然这么写太笨了
if (!query) {
const error = new Error('出错了')
error.error_code = 10001 // 可以这样改对象里面code
error.status = 400
error.requeset_url = ctx.method + ctx.path
throw Error
}
来写一个类class 继承 new Error
// 继承js内置的Error对象
class HttpException extends Error {
constructor(msg = '服务器异常', errorCode = 10000, code = 400) {
super()
this.errorCode = errorCode
this.code = code
this.msg = msg
}
}
module.exports = { HttpException }
数据校验
Lin-validators