Koa2框架快速入門與基本使用方式
本篇我們講一下 Koa2 框架的基本使用,希望能幫助大家快速上手
Koa2 是什么?簡單來講,它是一個(gè)基于 Node.js 的 web server 框架。

Koa2框架使用入門
不使用腳手架,直接使用Koa框架:
# 新建文件夾,控制臺(tái)進(jìn)入文件夾 npm init npm install koa
然后就可以新建js文件寫Koa代碼了。
帶有詳細(xì)注釋的示例代碼如下。
const Koa = require('koa')
const app = new Koa()
// ctx: context, 上下文
app.use((ctx) => {
ctx.body = 'hello koa!' // ctx.body即為HTTP響應(yīng)返回的數(shù)據(jù)(即響應(yīng)體中攜帶的數(shù)據(jù))
})
app.listen(3000) // 監(jiān)聽3000端口
// 瀏覽器地址欄輸入 http://localhost:3000/
使用腳手架koa-generator創(chuàng)建Koa項(xiàng)目:
# 安裝腳手架
npm install koa-generator -g
# 查看是否安裝成功
koa2 --version
# 或 koa --version
# 在當(dāng)前路徑下的指定文件夾創(chuàng)建koa項(xiàng)目(如果指定文件夾不存在則會(huì)創(chuàng)建)
koa2 <directory name> # 比如 koa2 demo
# 或者 koa <directory name>,如果使用 koa <directory name> 則創(chuàng)建的是koa1的項(xiàng)目
# 進(jìn)入以上指定的文件夾,執(zhí)行 npm install
cd <directory name>
npm install
# 開發(fā)環(huán)境下啟動(dòng)項(xiàng)目
npm run dev
# 瀏覽器訪問,地址欄輸入如下url(默認(rèn)端口號(hào)3000)
http://localhost:3000/
Koa2入門示例:新建路由、處理HTTP請(qǐng)求。帶有詳細(xì)注釋的示例代碼如下。
在routes文件夾下新建文件demo.js如下
// /routes/demo.js
const router = require('koa-router')()
router.prefix('/demo') // 路徑前綴
router.get('/', function (ctx) { // ctx即context,是req(request)和res(response)的集合
const query = ctx.query // 獲取url中的參數(shù)(以對(duì)象的形式表示)
console.log('query: ', query); // query: { xxx: 'xxx', ... }
ctx.body = 'this is get demo' // 返回?cái)?shù)據(jù)
})
router.post('/', function (ctx) {
const requestBody = ctx.request.body // 獲取請(qǐng)求體中的數(shù)據(jù)
console.log('request body: ', requestBody);
// Koa會(huì)根據(jù)返回的數(shù)據(jù)的格式自動(dòng)設(shè)置content-type
// ctx.body = 'this is post demo' // 自動(dòng)設(shè)置為text/plain
ctx.body = { errno: 0, message: 'this is post demo' } // 自動(dòng)設(shè)置為application/json
})
module.exports = router
在app.js文件下引入路由并且注冊(cè)路由
// /app.js
// 引入路由
const demo = require('./routes/demo')
// 注冊(cè)路由
app.use(demo.routes(), demo.allowedMethods())
Postman發(fā)送POST請(qǐng)求

中間件與洋蔥圈模型
中間件: 是指在整體流程上的一個(gè)獨(dú)立的業(yè)務(wù)模塊,其特點(diǎn)是可擴(kuò)展、可插拔,就類似于工廠流水線中的一道工序。

使用中間件的意義:
- 有助于將業(yè)務(wù)進(jìn)行模塊化拆分,讓代碼易寫易讀且便于維護(hù);
- 統(tǒng)一使用中間件,有助于各業(yè)務(wù)代碼的規(guī)范化與標(biāo)準(zhǔn)化;
- 易添加、易刪除、易擴(kuò)展。
對(duì)于Koa2框架來講:
- 所有的
app.use(...)都是中間件; - 中間件的回調(diào)函數(shù)不會(huì)在服務(wù)啟動(dòng)后立即執(zhí)行,而是只有當(dāng)收到網(wǎng)絡(luò)請(qǐng)求后才會(huì)按照順序執(zhí)行;
- 路由也是中間件的一種,當(dāng)收到網(wǎng)絡(luò)請(qǐng)求后會(huì)根據(jù)請(qǐng)求的
method和url進(jìn)行匹配,執(zhí)行對(duì)應(yīng)路由的回調(diào)函數(shù)。

Koa2中間件的回調(diào)函數(shù)通常具有如下形式:
async (ctx, next) => {
// ctx即context,是req(request)和res(response)的集合
// 執(zhí)行next()即相當(dāng)于調(diào)用下一個(gè)中間件的回調(diào)函數(shù)
// 為了讓代碼按照預(yù)期順序執(zhí)行,通常使用 await next() 的方式進(jìn)行使用
}
Koa2框架的中間件的執(zhí)行機(jī)制,即為洋蔥圈模型:

區(qū)分中間件與洋蔥圈模型: 中間件是Koa2框架中的業(yè)務(wù)模塊劃分,洋蔥圈模型是中間件的執(zhí)行機(jī)制(執(zhí)行順序)。
洋蔥圈模型演示:
// 洋蔥圈模型示例代碼
const Koa = require('koa')
const app = new Koa()
app.use(async (ctx, next) => {
console.log('1 start')
await next()
console.log('1 end')
})
app.use(async (ctx, next) => {
console.log('2 start')
await next()
console.log('2 end')
})
app.use(async (ctx, next) => {
console.log('3 start')
ctx.body = 'hello world'
console.log('3 end')
})
app.listen(3000)
console.log('server is running')
// 啟動(dòng)服務(wù)時(shí),控制臺(tái)打?。?
// server is running
// 瀏覽器訪問 http://localhost:3000/ 后,控制臺(tái)打?。?
// 1 start
// 2 start
// 3 start
// 3 end
// 2 end
// 1 end
若某一中間件中不調(diào)用next(),則其后的所有中間件都不會(huì)執(zhí)行。
// 某一中間件不調(diào)用next()
const Koa = require('koa')
const app = new Koa()
app.use((ctx, next) => {
console.log('1 start')
next()
console.log('1 end')
})
app.use(async (ctx, next) => {
console.log('2 start')
// await next()
console.log('2 end')
})
app.use(async (ctx, next) => {
console.log('3 start')
ctx.body = 'hello world'
console.log('3 end')
})
app.listen(3000)
console.log('server is running')
// 啟動(dòng)服務(wù)時(shí),控制臺(tái)打印:
// server is running
// 瀏覽器訪問 http://localhost:3000/ 后,控制臺(tái)打?。?
// 1 start
// 2 start
// 2 end
// 1 end
// 且瀏覽器不會(huì)顯示 hello world
中間件回調(diào)函數(shù)使用async定義,且next()前加await的意義在于如果后面的中間件中有異步操作(比如Promise),則能保證代碼按照期望的順序執(zhí)行。
不加async/await示例代碼及運(yùn)行結(jié)果:
// 不加async/await
const Koa = require('koa')
const app = new Koa()
app.use((ctx, next) => {
console.log('1 start')
next()
console.log('1 end')
})
app.use(() => {
console.log('2 start')
new Promise((resolve, reject) => {
setTimeout(() => { resolve('hello') }, 0)
})
.then((data) => { console.log(data) })
.then((data) => { console.log(data) })
console.log('2 end');
})
app.listen(3000)
// 瀏覽器訪問 http://localhost:3000/ 后,控制臺(tái)打?。?
// 1 start
// 2 start
// 2 end
// 1 end
// hello
// undefined
加async/await示例代碼及運(yùn)行結(jié)果:
const Koa = require('koa')
const app = new Koa()
app.use(async (ctx, next) => {
console.log('1 start')
await next()
console.log('1 end')
})
app.use(async () => {
console.log('2 start')
await new Promise((resolve, reject) => {
setTimeout(() => { resolve('hello') }, 0)
})
.then((data) => { console.log(data) })
.then((data) => { console.log(data) })
console.log('2 end');
})
app.listen(3000)
// 瀏覽器訪問 http://localhost:3000/ 后,控制臺(tái)打?。?
// 1 start
// 2 start
// hello
// undefined
// 2 end
// 1 end
總結(jié)
至此,Koa2的入門使用就介紹完了~
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
React+react-dropzone+node.js實(shí)現(xiàn)圖片上傳的示例代碼
本篇文章主要介紹了React+react-dropzone+node.js實(shí)現(xiàn)圖片上傳的示例代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-08-08
詳解nodejs微信公眾號(hào)開發(fā)——6.自定義菜單
這篇文章主要介紹了詳解nodejs微信公眾號(hào)開發(fā)——6.自定義菜單,自定義菜單能夠幫助公眾號(hào)豐富界面,讓用戶更好更快地理解公眾號(hào)的功能。2017-04-04
Node.js?中常用內(nèi)置模塊(path?路徑模塊)
這篇文章主要介紹了Node.js?中常用內(nèi)置模塊(path?路徑模塊),文章圍繞主題展開詳細(xì)的相關(guān)介紹,具有一定的參考價(jià)值,感興趣的朋友可以參考一下2022-09-09

