在前文已经简单的了解了 Express 框架,并且使用该框架对石头剪刀布游戏进行了改造,那么来看看 Koa 框架和 Express 框架有什么不同,然后用 Koa 框架对石头剪刀布游戏进行改造吧!【推荐学习:《nodejs 教程》】
Koa
Koa
是为了解决 Express
的一些设计缺陷而诞生的。它的中间件可以通过 async function
来编写,await next()
可以中断中间件的执行,等到后面所有中间件执行完之后再执行,通过 await next()
来实现洋葱模型。
还有一个特点是对 request
和 response
的简化处理,这两者都挂载在 ctx
上使用,返回的内容也可以通过直接赋值来使用,如:ctx.response.body = fs.createStream('really_large.xml')
。
而且 Koa
把路由功能砍掉了,它是通过中间件来实现的,这是一种微内核的极简思路。
核心功能(Koa
的说明文档):
- 比
Express
更极致的request
/response
简化,如:ctx.status = 200
ctx.body = 'hello node'
- 使用
async function
实现的中间件。 - 有“暂停执行”的能力。
- 在异步的情况下也符合洋葱模型。
- 精简内核,所有额外功能都移到中间件里实现。
Koa 改造石头剪刀布游戏
同样,game.js
游戏模块和 index.html
页面的代码没有变动,需要安装依赖包:koa
和 koa-mount
(npm i koa koa-mount
)
koa-mount
可以将其它应用程序作为中间件挂载,传递给 mount()
函数的路径参数暂时从 url
里剥离出来,直到堆栈释放。对于创建不管用于那个路径且功能正常的整个 app
或 中间件是很有用。它把中间件挂载到一个特定的路径上,中间件独立于这个路径动作。
index.js
代码改造:
// 加载模块
const fs = require('fs');
const koa = require('koa');
const mount = require('koa-mount');
const game = require('./game');
let playerWon = 0; // 赢的次数
const app = new koa();
// 精简内核,所有额外功能都移到中间件里实现。路由使用通过 mount 的中间件实现的
// 通过 mount() 把中间件挂载到一个特定的路径上,中间件独立于这个路径动作。
// /favicon.ico 路径的路由
app.use(
mount('/favicon.ico', function (ctx) {
// 对 `request` 和 `response` 的处理简化了,这两者都挂载在 `ctx` 上使用,返回的内容也可以通过直接赋值来使用
ctx.status = 200;
return;
})
)
// mount中不可以跟多个函数中间件,可以通过 new koa() 来挂载在 koa 上:
const gameKoa = new koa();
app.use(
mount('/game', gameKoa)
)
// 分离模块
gameKoa.use(
async function (ctx, next) {
if (playerWon >= 3) {
// response.status(500);
// response.send('我不会再玩了!');
// 使用 = 赋值,更加简化了
ctx.status = 500;
ctx.body = '我不会再玩了!';
return;
}
// 通过next执行后续中间件
await next();
// 当后续中间件执行完之后,会执行到这个位置
if (ctx.playerWon) {
playerWon++;
}
}
)
// 在 koa 里可以使用 async function 和 await next() 来执行异步中间件
// 使在异步的情况下也符合洋葱模型。
gameKoa.use(
async function (ctx, next) {
const query = ctx.query;
const playerAction = query.action;
if (!playerAction) {
ctx.status = 400;
return;
}
ctx.playerAction = playerAction;
await next();
}
)
// 异步处理,500ms后才返回结果
gameKoa.use(
async function (ctx, next) {
const playerAction = ctx.playerAction;
const result = game(playerAction);
// 对于一定需要在请求主流程里完成的操作,一定要使用await进行等待
// 否则koa就会在当前事件循环就把http response返回出去了
await new Promise(resolve => {
setTimeout(() => {
ctx.status = 200;
if (result == 0) {
ctx.body = '平局'
} else if (result == -1) {
ctx.body = '你输了'
} else {
ctx.body = '你赢了'
ctx.playerWon = true;
}
resolve();
}, 500)
})
}
)
// 打开页面 index.html
app.use(
mount('/', function (ctx) {
ctx.body = fs.readFileSync(__dirname + '/index.html', 'utf-8')
return;
})
)
// 监听端口 3000
app.listen(3000);
Express VS Koa
Express
门槛更低,Koa
更强大优雅。Express
封装更多东西,开发更快速,Koa
可定制型更高。
它们孰“优”孰“劣”?
- 其实框架之间并没有优劣之分
- 不同的框架有不同的适用场景
更多编程相关知识,请访问:编程视频!!
以上就是深入了解Node.js中的Koa框架的知识。速戳>>知识兔学习精品课!