本篇文章給大家詳細(xì)介紹一下Node.js中的Koa框架。有一定的參考價(jià)值,有需要的朋友可以參考一下,希望對(duì)大家有所幫助。

在前文已經(jīng)簡單的了解了 Express 框架,并且使用該框架對(duì)石頭剪刀布游戲進(jìn)行了改造,那么來看看 Koa 框架和 Express 框架有什么不同,然后用 Koa 框架對(duì)石頭剪刀布游戲進(jìn)行改造吧!【推薦學(xué)習(xí):《nodejs 教程》】
Koa
Koa 是為了解決 Express 的一些設(shè)計(jì)缺陷而誕生的。它的中間件可以通過 async function 來編寫,await next() 可以中斷中間件的執(zhí)行,等到后面所有中間件執(zhí)行完之后再執(zhí)行,通過 await next() 來實(shí)現(xiàn)洋蔥模型。
還有一個(gè)特點(diǎn)是對(duì) request 和 response 的簡化處理,這兩者都掛載在 ctx 上使用,返回的內(nèi)容也可以通過直接賦值來使用,如:ctx.response.body = fs.createStream('really_large.xml')。
而且 Koa 把路由功能砍掉了,它是通過中間件來實(shí)現(xiàn)的,這是一種微內(nèi)核的極簡思路。
核心功能(Koa 的說明文檔):
- 比 Express 更極致的 request / response 簡化,如:
- ctx.status = 200
- ctx.body = 'hello node'
- 使用 async function 實(shí)現(xiàn)的中間件。
- 有“暫停執(zhí)行”的能力。
- 在異步的情況下也符合洋蔥模型。
- 精簡內(nèi)核,所有額外功能都移到中間件里實(shí)現(xiàn)。
Koa 改造石頭剪刀布游戲
同樣,game.js 游戲模塊和 index.html 頁面的代碼沒有變動(dòng),需要安裝依賴包:koa 和 koa-mount(npm i koa koa-mount)
koa-mount 可以將其它應(yīng)用程序作為中間件掛載,傳遞給 mount() 函數(shù)的路徑參數(shù)暫時(shí)從 url 里剝離出來,直到堆棧釋放。對(duì)于創(chuàng)建不管用于那個(gè)路徑且功能正常的整個(gè) app 或 中間件是很有用。它把中間件掛載到一個(gè)特定的路徑上,中間件獨(dú)立于這個(gè)路徑動(dòng)作。
index.js 代碼改造:
// 加載模塊
const fs = require('fs');
const koa = require('koa');
const mount = require('koa-mount');
const game = require('./game');
let playerWon = 0; // 贏的次數(shù)
const app = new koa();
// 精簡內(nèi)核,所有額外功能都移到中間件里實(shí)現(xiàn)。路由使用通過 mount 的中間件實(shí)現(xiàn)的
// 通過 mount() 把中間件掛載到一個(gè)特定的路徑上,中間件獨(dú)立于這個(gè)路徑動(dòng)作。
// /favicon.ico 路徑的路由
app.use(
mount('/favicon.ico', function (ctx) {
// 對(duì) `request` 和 `response` 的處理簡化了,這兩者都掛載在 `ctx` 上使用,返回的內(nèi)容也可以通過直接賦值來使用
ctx.status = 200;
return;
})
)
// mount中不可以跟多個(gè)函數(shù)中間件,可以通過 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('我不會(huì)再玩了!');
// 使用 = 賦值,更加簡化了
ctx.status = 500;
ctx.body = '我不會(huì)再玩了!';
return;
}
// 通過next執(zhí)行后續(xù)中間件
await next();
// 當(dāng)后續(xù)中間件執(zhí)行完之后,會(huì)執(zhí)行到這個(gè)位置
if (ctx.playerWon) {
playerWon++;
}
}
)
// 在 koa 里可以使用 async function 和 await next() 來執(zhí)行異步中間件
// 使在異步的情況下也符合洋蔥模型。
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后才返回結(jié)果
gameKoa.use(
async function (ctx, next) {
const playerAction = ctx.playerAction;
const result = game(playerAction);
// 對(duì)于一定需要在請(qǐng)求主流程里完成的操作,一定要使用await進(jìn)行等待
// 否則koa就會(huì)在當(dāng)前事件循環(huán)就把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;
})
)
// 監(jiān)聽端口 3000
app.listen(3000);
Express VS Koa
- Express 門檻更低,Koa 更強(qiáng)大優(yōu)雅。
- Express 封裝更多東西,開發(fā)更快速,Koa 可定制型更高。
它們孰“優(yōu)”孰“劣”?
- 其實(shí)框架之間并沒有優(yōu)劣之分
- 不同的框架有不同的適用場景
本文轉(zhuǎn)載自:https://www.php.cn/js-tutorial-478030.html
更多編程相關(guān)知識(shí),請(qǐng)?jiān)L問:編程視頻!!