本文仓库地址 github.com/LuckyChou71…
官网 koajs.com/
Koa
koa 支持 async 和 await 的用法
这就意味着在 koa 中可以抛去 express 中回调函数的写法 用一种更优雅的方式来解决异步场景
基本使用
与 express 不同的是 koa 导出的不是函数 而是一个名为 Application 的对象
所以在使用上我们只需要 new 一个实例即可 其他用法和 Express 基本相似
const Koa = require('koa');
const app = new Koa();
app.listen(3000, () => {
console.log('server start...');
});
Koa 本身十分纯净 几乎大部分的功能都是通过插件的方式来实现
路由
这里我们借助第三方模块 koa-router
新建一个 user.js 的路由模块
Koa 将 express 中的 request 和 response 都合成到了上下文对象 context 中 简写为 ctx
const Router = require('koa-router');
const userRouter = new Router({ prefix: '/user' });
userRouter.get('/home', (ctx, next) => {
ctx.body = 'welcome~~';
});
userRouter.post('/login', (ctx, next) => {
ctx.body = 'login...';
});
module.exports = userRouter;
然后在 index 中引入 user.js
const Koa = require('koa');
const userRouter = require('./router/user');
const app = new Koa();
app.use(userRouter.routes());
app.listen(3000, () => {
console.log('server start...');
});
然后访问 http://localhost:3000/user/home 我们就可以看到
处理请求
koa 中需要引入 koa-bodyparser 来解析 json 和 urlencoded
const Koa = require("koa");
const Router = require("koa-router");
const bodyParser = require("koa-bodyparser");
const app = new Koa();
const router = new Router();
app.use(bodyParser());
app.use(router.routes());
// 解析query
router.get("/query", (ctx, next) => {
console.log(ctx.request.query);
});
// 解析params
router.get("/params/:id", (ctx, next) => {
console.log(ctx.request.params);
});
// 解析urlencoded
router.post("/urlencoded", (ctx, next) => {
console.log(ctx.request.body);
});
// 解析json
router.post("/json", (ctx, next) => {
console.log(ctx.request.body);
});
app.listen(8080, () => {
console.log("start");
});
- query
- params
- urlencoded
- json
注意 koa-bodyparser 中间件需要最先被使用
异步处理
Koa 的中间件支持 async / await 的语法 例如下面这个demo就可以正常拼接ABC输出
const express = require('express');
const app = express();
const middlewareA = (req, res, next) => {
req.message = '';
req.message += 'A';
next();
res.end(req.message);
};
const middlewareB = async (req, res, next) => {
req.message += await Promise.resolve('B');
await next();
};
const middlewareC = (req, res, next) => {
req.message += 'C';
next();
};
app.use(middlewareA);
app.use(middlewareB);
app.use(middlewareC);
app.listen(3000, () => {
console.log('server start...');
});
访问 http://localhost:3000 就可以看到
出现 Not Found 是因为我们并未配置路有 但是可以后面的ABC已经正确输出了
洋葱模型
洋葱模型其实不是什么高大尚的概念 先来看一个demo
const Koa = require('koa');
const app = new Koa();
const middlewareA = (ctx, next) => {
console.log('middlewareA');
next();
console.log('middlewareA');
};
const middlewareB = (ctx, next) => {
console.log('middlewareB');
next();
console.log('middlewareB');
};
const middlewareC = (ctx, next) => {
console.log('middlewareC');
next();
console.log('middlewareC');
};
app.use(middlewareA);
app.use(middlewareB);
app.use(middlewareC);
app.listen(3000, () => {
console.log('server start');
});
访问 3000 端口 我们可以看到 控制台输出
middlewareA
middlewareB
middlewareC
middlewareC
middlewareB
middlewareA
通过下图我们不难发现 所有中间件都会被 request 访问两次 就像剥洋葱一样 这就是洋葱模型
注意 Express 同样也是洋葱模型
express 对比 koa
-
express 是完整和强大的,其中帮助我们内置了非常多好用的功能;
-
koa 是简洁和自由的,它只包含最核心的功能,并不会对我们使用其他中间件进行任何的限制。 甚至是在 app 中连最基本的 get、post 都没有给我们提供;我们需要通过自己或者路由来判断请求方式或者其他功能