koa2學習筆記

是曾小白吖發表於2020-02-19

一 koa-generateor

1.全域性安裝generator

npm install -g koa-generator
複製程式碼

2.新建koa2專案

// 使用es引擎建立專案
koa2 -e koa2-learn
複製程式碼

3.啟動專案

npm start,
// 可以自啟動
npm run dev 
複製程式碼

二 async(非同步)和await(等待)語法

1.非同步的概念

同步:任務按排列順序執行。

非同步:其實就是延遲處理,在和html互動的過程中,會需要一些IO操作(典型的就是ajax請求,指令碼檔案載入),如果這些操作是同步的,使用者的體驗就是頁面失去了響應,非同步是通過非同步函式實現的,如setTimeout()。實現方式從最開始的回撥函式,到promise,再到ES6中的async/await。

2.Promise

  1. promise的狀態 promise的三種狀態:pending(非同步操作未完成),resolved(非同步操作已完成),rejected(非同步操作失敗)。promise的2種結果(resolved,rejected),非同步操作成功promise傳回一個值,狀態為resolved,非同步操作失敗promise物件丟擲一個錯誤,狀態變為rejected。
  2. promise的用途:用於非同步計算;將非同步操作佇列話,按照期望的順序執行,返回符合預期的結果;可以在物件之間傳遞和操作promise,幫助我們處理佇列;它就是一個容器,裡面儲存著某個未來才會結束的事件(通常是一個非同步操作)的結果。
  3. promise的2個特點:物件的狀態不受外界的影響,只有非同步操作的結果可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態;一旦狀態改變就不會再變,任何時候都可以得到這個結果。
  4. promise的缺點:一旦新建一個promise就會立即執行,無法中途取消;如果不設定回撥函式,promise的錯誤不會反應到外部;出於pending狀態時,無法得知當前進行到哪一步。
new promise(
  // 執行器
  function (resolve, reject) { // 一段耗時很長的非同步操作
      resolve(); // 資料處理完成
      reject(); //資料處理出錯
  }
).then( function A() { //成功,下一步
  }, function B(){ //失敗,下一步
  })
複製程式碼

koa2學習筆記

3.async/await

await後面接一個會return new promise的函式並執行它

await只能放在async函式裡

例:使用async和await獲取成功的結果

function action1(){
  return new Promise((resolve, reject)=>{
    let sino = parseInt(Math.random() * 6 +1)
    setTimeout(()=>{
      resolve(sino)
    },3000)
  })
}
async function test(){
    let n =await action1()
    console.log(n)
}
test()
複製程式碼

上面這段程式碼async中使await action1()先執行,等到三秒後執行完再把得到的結果賦值給左邊的n,也就是說test函式需要三秒鐘才執行完成,所以test函式是非同步的,因此前面必須寫async

例:使用async和await獲取失敗的結果

function action2(猜測){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 6 +1)
        if(sino > 3){
            if(猜測 === '大'){
                resolve(sino)
            }else{
                reject(sino)
            }
        }else{
            if(猜測 === '大'){
                reject(sino)
            }else{
                resolve(sino)
            }
        }
        setTimeout(()=>{
            resolve(sino)
        },300)
    })
}
async function test(){
    try{
        //把await及獲取它的值的操作放在try裡
        let n =await action2('大')
        console.log('贏了' + n)
    }catch(error){
      //失敗的操作放在catch裡
        console.log('輸了' + error)
    }
}
test()
複製程式碼

把await和成功後的操作放到try裡,失敗的放在catch。

例:使用promise拿到所有的promise都結束後的結果

Promise.all([action2('大'),action2('大')]).then((x)=>{
    console.log(x)
},(y)=>{
    console.log(y)
})
複製程式碼

promise.all裡面跟一個陣列,陣列的每一項呼叫一個返回promise的函式,then的第一個引數是所有的promise都成功後返回sino值的一個陣列;第二個引數拿到的是第一個失敗的sino值。

例:使用await拿到所有的promise都結束後的結果

async function test(){
    try{
       let n = await promise.all([action2('大'),action2('大')]) 
       console.log(n)
    }catch(error){
        console.log(error)
    }
}
test()
複製程式碼

async函式會返回一個promise,並且Promise物件的狀態值是resolved(成功的)

例:如果asycn裡的程式碼都是同步的,那麼這個函式被呼叫就會同步執行

async function fn(){
  console.log('a')
}
fn()
console.log('b')
//a
//b
複製程式碼

三 koa2中介軟體

koa2學習筆記

示例:

app.use(async (ctx,next) =>{
    console.log(1);
    await next() //繼續往下執行下一個中介軟體,next非常重要,一定要寫,不然後面的中介軟體無法執行
    console.log(2);
});
 
app.use(async (ctx,next) =>{
    console.log(3);
    const axios = require('axios');
    const res = await axios.get('https://www.baidu.com/');
    console.log(4);
});
複製程式碼

想要保證洋蔥模型的話就要使用async/await(必須在方法前面加上async,在next()前面加上await),下面的程式碼的執行順序就變成了標準的洋蔥模型,1,3,4,2

四 koa2路由

檢視相關api地址:github.com/ZijianHe/ko…

示例:

const router = require('koa-router')()

// render:渲染頁面的
router.get('/', async (ctx, next) => {
  await ctx.render('index', {
    title: 'Hello Koa 2!'
  })
})


// ctx.body:用來寫介面的
router.get('/string', async (ctx, next) => {
  ctx.body = 'koa2 string'
})

router.get('/json', async (ctx, next) => {
  ctx.body = {
    title: 'koa2 json'
  }
})

router.get('/testAsync', async (ctx) => {
  console.log('start', new Date().getTime())
  const a = await new Promise((resolve, reject) => {
    setTimeout(function () {
      console.log('async a', new Date().getTime())
      resolve('3333')
    }, 1000)
  })
  ctx.body = {
    a
  }
})

module.exports = router //最後不要忘記匯出,匯出後在app.js裡面使用app.use(XX)
複製程式碼

給所有路徑加字首,相當於模組化:

router.prefix('/users'); // 路由模組化;
 
// 訪問這個頁面 http://localhost:3000/users/bar
router.get('/bar', function (ctx, next) {
  ctx.body = 'this is a users/bar response'
})
複製程式碼

五 cookie和session

檢視相關api地址:koa.bootcss.com/#introducti…

//cookies用法
ctx.cookies.set('name', 'tobi', { signed: true });
複製程式碼

session:服務端用session來儲存使用者狀態和標識。 session和cookie的關係是:服務端把session設定到cookie裡傳遞給客戶端,客戶端下次訪問伺服器其他介面時又會通過cookie把這個session資訊傳給服務端,服務端以此來進行判斷使用者許可權。