介紹
koa,是基於Node.js 平臺的下一代的web開發框架。
是由Express原班人馬打造,致力於成為一個更小的,更加富有表現力的,web框架。
使用koa編寫web應用,可以免除重複的回撥函式巢狀,並極大的提高錯誤處理的效率,
koa框架不僅僅在核心方法中可以繫結任何中介軟體,它僅僅提供了一個輕量級,優雅的函式庫,思路和express相差不少。
koa框架的安裝
安裝koa
安裝koa框架和安裝之前的模組一樣。
使用如下命令安裝
npm install --save koa
使用save引數,表明將會自動修改package.json 檔案。自動新增依賴項
hello world
輸入如下的程式碼,執行hello world
const koa = require("koa");
const app = new koa();
// 配置中介軟體
app.use(async (ctx) => {
ctx.body = "hello world";
})
// 監聽埠
app.listen(3000);
執行檔案
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
輸出結果如下
非同步的處理
由於js是單執行緒的,所以,使用回撥函式處理非同步等問題。
回撥函式處理
const koa = require("koa");
const app = new koa();
function getData(callback){
setTimeout(function () {
var name = "ming";
callback(name);
}, 1000)
}
// 從外部獲取非同步方法裡的資料
getData(function (data) {
console.log(data)
})
// 監聽埠
app.listen(3000);
輸出結果
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
ming
使用promise處理非同步
const koa = require("koa");
const app = new koa();
// promise 處理非同步
// resolve 成功的回撥函式
// reject 失敗的回撥函式
var p = new Promise(function (resolve, reject) {
setTimeout(function () {
var name = "張三";
}, 1000)
})
// 獲取非同步的結果
p.then((data) => {
console.log(data);
})
// 監聽埠
app.listen(3000);
執行結果如下
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
ming
關於async await promise
其中async是非同步的縮寫,await被認為是async wait的縮寫,所以,async用於申明一個函式為非同步的,await用於等待一個非同步方法執行完成。
簡單理解
async 讓方法變成非同步
await 等待非同步方法執行完成。
async
實際例子
這裡使用實際的例子,更好理解。
同步函式
function getData(){
return "ming";
}
console,log(getData())
輸出結果
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
ming
async 可以讓該方法變成非同步
const koa = require("koa");
const app = new koa();
// promise 處理非同步
// resolve 成功的回撥函式
// reject 失敗的回撥函式
async function getData(){
return "這是一個資料";
}
console.log(getData());
// 監聽埠
app.listen(3000);
輸出結果如下所示
其中promise為一個非同步的資料
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
Promise { '這是一個資料' }
獲取該資料
const koa = require("koa");
const app = new koa();
// promise 處理非同步
// resolve 成功的回撥函式
// reject 失敗的回撥函式
async function getData(){
return "這是一個資料";
}
var p = getData();
p.then((data) => {
console.log(data);
})
// 監聽埠
app.listen(3000);
輸出結果如圖所示
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
這是一個資料
await
使用await方法獲取到非同步的資訊
const koa = require("koa");
const app = new koa();
// promise 處理非同步
// resolve 成功的回撥函式
// reject 失敗的回撥函式
async function getData(){
return "這是一個資料";
}
async function test(){
// 此時執行的為,發現該函式是一個非同步函式,遇到了await進入等待狀態,等待getData執行完畢,再往下執行
var d = await getData();
console.log(d)
}
test()
// 監聽埠
app.listen(3000);
執行結果
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
這是一個資料
koa 路由
路由是根據不同的url地址,載入不同頁面實現不同的功能。
安裝路由
npm install --save koa-router
使用路由
const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
router.get("/", (ctx, next) => {
ctx.body = "ming";
})
// 啟動路由
app.use(router.routes());
app.use(router.allowedMethods());
// 監聽埠
app.listen(3000);
執行結果如下所示
其中可以新增async作為非同步方法來呼叫
const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
router.get("/", async (ctx, next) => {
ctx.body = "ming";
})
// 啟動路由
app.use(router.routes());
// 設定響應頭
app.use(router.allowedMethods());
// 監聽埠
app.listen(3000);
獲取連結的引數值
通過router獲取路由的引數值
連結為
獲取格式化好的
http://localhost:3000/?ming=3
程式碼為
const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
router.get("/", async (ctx, next) => {
// query 返回的是格式化好的引數物件
// querystring 返回的是請求的字串
console.log(ctx.query)
ctx.body = "ming";
})
// 啟動路由
app.use(router.routes());
// 設定響應頭
app.use(router.allowedMethods());
// 監聽埠
app.listen(3000);
訪問的結果是
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
[Object: null prototype] { ming: '3' }
獲取未格式化好的
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
ming=3
const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
router.get("/", async (ctx, next) => {
// query 返回的是格式化好的引數物件
// querystring 返回的是請求的字串
console.log(ctx.querystring)
ctx.body = "ming";
})
// 啟動路由
app.use(router.routes());
// 設定響應頭
app.use(router.allowedMethods());
// 監聽埠
app.listen(3000);
設定動態路由
const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 配置動態路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的引數物件
// querystring 返回的是請求的字串
console.log(ctx.params)
ctx.body = "ming";
})
// 啟動路由
app.use(router.routes());
// 設定響應頭
app.use(router.allowedMethods());
// 監聽埠
app.listen(3000);
訪問的連結為
http://localhost:3000/ming
輸出的內容
PS C:\Users\Administrator\IdeaProjects\untitled3> node ./ming.js
{ id: 'ming' }
koa 中介軟體
這裡配置koa的中介軟體
中介軟體就是匹配路由完成做的一系列的操作,把它稱之為中介軟體。
中介軟體的功能主要有:
- 執行任何程式碼
- 修改請求和響應的物件
- 終結請求,響應迴圈
- 呼叫堆疊中的下一個中介軟體。
需求: 列印出中介軟體相關內容
const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 中介軟體
app.use(async (ctx) => {
ctx.body = "這是一箇中介軟體";
})
// 配置動態路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的引數物件
// querystring 返回的是請求的字串
console.log(ctx.params)
ctx.body = "ming";
})
// 啟動路由
app.use(router.routes());
// 設定響應頭
app.use(router.allowedMethods());
// 監聽埠
app.listen(3000);
執行結果
此時訪問任何頁面出現的都是這個內容,
持續匹配
因為訪問的時候,沒有加上next,此時造成的無法進入到匹配路由的階段。
const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 中介軟體
app.use(async (ctx, next) => {
ctx.body = "這是一箇中介軟體";
// 進入路由匹配
next();
})
// 配置動態路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的引數物件
// querystring 返回的是請求的字串
console.log(ctx.params)
ctx.body = "ming";
})
// 啟動路由
app.use(router.routes());
// 設定響應頭
app.use(router.allowedMethods());
// 監聽埠
app.listen(3000);
由於js是單執行緒的,此時需要新增await,進行訪問。
const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 中介軟體
app.use(async (ctx, next) => {
ctx.body = "這是一箇中介軟體";
// 進入路由匹配
await next();
})
// 配置動態路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的引數物件
// querystring 返回的是請求的字串
console.log(ctx.params)
ctx.body = "ming";
})
// 啟動路由
app.use(router.routes());
// 設定響應頭
app.use(router.allowedMethods());
// 監聽埠
app.listen(3000);
路由持續匹配
路由由於沒有await next,造成路由匹配到以後就不再匹配,所以新增next,能把兩個相同的路由按照順序,匹配完成。
const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 中介軟體
app.use(async (ctx, next) => {
ctx.body = "這是一箇中介軟體";
// 進入路由匹配
await next();
})
// 配置動態路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的引數物件
// querystring 返回的是請求的字串
console.log(ctx.params)
ctx.body = "ming";
await next();
})
router.get("/:id", async (ctx, next) => {
// 此時匹配到這點
await next();
})
// 啟動路由
app.use(router.routes());
// 設定響應頭
app.use(router.allowedMethods());
// 監聽埠
app.listen(3000);
中介軟體的執行順序
錯誤處理中介軟體
// 中介軟體
app.use(async (ctx, next) => {
console.log("這是一箇中介軟體");
// 進入洋蔥
next()
// 出洋蔥
if(ctx.status = 404){
ctx.status = 404;
ctx.body = "這是一個 404 頁面";
}
})
第三方中介軟體
例如進行靜態檔案託管的時候,使用的是第三方中介軟體
const static = require('koa-static');
const staticPath = './static';
app.use(static(
path.join(__dirname, staticPath);
))
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
這樣就完成了靜態檔案託管