KOA 官網鏈接
當然,如果你有express的基礎就最好了,畢竟是原班人馬開發
常用的指令
npm install koa
npm install nodemon
touch app.js
nodemon app.js
測試一
use
use
函數 使用中間件
app.js
const Koa = require('koa')
const app = new Koa()
app.use((ctx,next)=>{
console.log(1)
console.log(2)
})
app.use((ctx,next)=>{
console.log(3)
console.log(4)
})
app.listen(1019)
nodemon app.js
// 瀏覽器運行localhst:1019 輸出
1
2
測試二
next()
next
函數主要負責將控制權交給下一個中間件,如果當前中間件沒有終結請求,並且next沒有被調用,那麼當前中間件的請求將被掛起,等到next()後的中間件執行完再返回繼續執行。總結來說,就是:從第一個中間件開始執行,遇到next進入下一個中間件,一直執行到最後一箇中間件,在逆序,執行上一個中間件next之後的代碼,一直到第一個中間件執行結束才發出響應。如下代碼
const Koa = require('koa')
const app = new Koa()
app.use((ctx,next)=>{
console.log(1)
next()
console.log(2)
})
app.use((ctx,next)=>{
console.log(3)
next() // 下一個中間件沒有 按下執行 4
console.log(4)
})
app.listen(1019)
nodemon app.js
//輸出
1
3
4
2
這可以說是一個最最最基本的洋蔥模型,先進去再出來
測試三
const Koa = require('koa')
const app = new Koa()
app.use((ctx,next)=>{
console.log(1)
next() // 初次進入下個組件
console.log(2)
})
app.use((ctx,next)=>{
console.log(3)
next() // 初次進入下個組件
console.log(4)
})
app.use((ctx,next)=>{
console.log(5)
next() // 初次進入下個組件
console.log(6) // 沒有下個組件 再組件向上
})
app.listen(1019)
// 輸出
1
3
5
6
4
2
測試四
const Koa = require('koa')
const app = new Koa()
app.use((ctx,next)=>{
console.log(1)
const a = next()
console.log(a)
console.log(2)
})
app.use((ctx,next)=>{
console.log(3)
console.log(4)
})
app.listen(1019)
1
3
4
Promise { undefined } //因爲上一個中間件沒有返回值 ,如果return一個值,則有值 promise
2
如果對promise不太清楚的地方,可以點這裏 Promise 和 Promise 與 異步機制
插一嘴,async 加在函數前,哪怕普通函數,也會強制轉換成promise對象。控制檯 輸出打印後會有undefined,說明一個線程結束
測試五
const Koa = require('koa')
const app = new Koa()
app.use((ctx,next)=>{
console.log(1)
const a = next()
console.log(a)
console.log(2)
})
app.use((ctx,next)=>{
console.log(3)
console.log(4)
return "中間件可以return"
})
app.listen(1019)
1
3
4
Promise { '中間件可以return' }
2
案例六
async
用於申明一個function是異步的,而await
認爲是async wait
的簡寫,等待一個異步方法的完成。
const Koa = require('koa')
const app = new Koa()
app.use( async(ctx,next)=>{
console.log(1)
const a = await next() // 或者不用按async await .then((res)=>{})
console.log(a)
console.log(2)
})
app.use((ctx,next)=>{
console.log(3)
console.log(4)
return "中間件可以return"
})
app.listen(1019)
1
3
4
中間件可以return
2
測試七
線程阻塞問題
測試七-1
const Koa = require('koa')
const app = new Koa()
app.use( async(ctx,next)=>{
console.log(1)
const a = await next()
console.log(a)
})
app.use((ctx,next)=>{
const axios = require('axios')
const start = Date.now()
const res = axios.get('http://www.baidu.com')
const end = Date.now()
console.log(end-start)
})
app.listen(1019)
// 輸出
1
1 // 這裏返回 0或者1或者2 幾乎可以忽略不計 不阻塞 可以認爲沒有等待上個axios.get()請求完成後再執行下一步
測試七-2
const Koa = require('koa')
const app = new Koa()
app.use( async(ctx,next)=>{
console.log(1)
const a = await next()
console.log(a)
})
app.use(async(ctx,next)=>{
const axios = require('axios')
const start = Date.now()
const res = await axios.get('http://www.baidu.com')
const end = Date.now()
console.log(end-start)
})
app.listen(1019)
1
110 耗時較多 阻塞
測試七-3
const Koa = require('koa')
const app = new Koa()
app.use( async(ctx,next)=>{
console.log(1)
next()
console.log(2)
})
app.use(async(ctx,next)=>{
console.log(3)
const axios = require('axios')
const res = await axios.get('http://www.baidu.com') //線程阻塞返回上一個組件
next()
console.log(4)
})
app.listen(1019)
// 返回沒有按照洋蔥模型執行
1
3
2
4
確保每個中間件按照洋蔥模型執行
async()=>{
await next()
}
測試七-4
const Koa = require('koa')
const app = new Koa()
app.use( async(ctx,next)=>{
console.log(1)
await next()
console.log(2)
})
app.use(async(ctx,next)=>{
console.log(3)
const axios = require('axios')
const res = await axios.get('http://www.baidu.com')
next()
console.log(4)
})
app.listen(1019)
// 返回按照洋蔥模型執行
1
3
4
2
測試八
自己寫的中間件,return 傳遞數組,是沒有問題的。但是如果使用第三方插件,就不太方便了。所以koa使用了一個全局上下文對象ctx。類似於window,一個全局對象,你就會window.xx。
const Koa = require('koa')
const app = new Koa()
app.use( async(ctx,next)=>{
console.log(1)
await next()
console.log(ctx.htmlData)
})
app.use(async(ctx,next)=>{
console.log(3)
const axios = require('axios')
const res = await axios.get('http://www.baidu.com')
ctx.htmlData = res
next()
console.log(4)
})
app.listen(1019)
// 百度的信息
'<!DOCTYPE html>\n<!--STATUS OK--><html>\n<head>\n
\n <meta http-equiv="content-type" content="text/html;charset=utf-8">\n <meta http-equiv="X-UA-Compatible" content="IE=Edge">\n\t<meta content="always" name="referrer">\n
<meta name="theme-color" content="#2932e1">\n <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />\n <link rel="search" type="application/opensearchdescription+xml" href="/content-search.xml" title="百度搜索" />\n <link rel="icon" sizes="any" mask href="//www.baidu.com/img/baidu_85beaf5496f291521eb75ba38eacbd87.svg">\n\t\n\t\n\t<link rel="dns-prefetch" href="//s1.bdstatic.com"/>\n\t<link rel="dns-prefetch" href="//t1.baidu.com"/>\n\t<link rel="dns-prefetch" href="//t2.baidu.com"/>\n\t<link rel="dns-prefetch" href="//t3.baidu.com"/>\n\t<link rel="dns-prefetch" href="//t10.baidu.com"/>\n\t<link rel="dns-prefetch" href="//t11.baidu.com"/>\n\t<link rel="dns-prefetch" href="//t12.baidu.com"/>\n\t<link rel="dns-prefetch" href="//b1.bdstatic.com"/>\n \n <title>百度一下,你就知道</title>\n \n\n<style id="css_index" index="index" type="text/css">html,body{height:100%}\nhtml{overflow-y:auto}\nbody{font:12px arial;text-align:;background:#fff}\nbody,p,form,ul,li{margin:0;padding:0;list-style:none}\nbody,form,#fm{position:relative}\ntd{text-align:left}\nimg{border:0}\na{color:#00c}\na:active{color:
初探就這樣了,喜歡的點個贊。如果有疑問出入,歡迎交流。