koa2学习笔记

1,172 阅读4分钟

一 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(){ //失败,下一步
  })

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中间件

示例:

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信息传给服务端,服务端以此来进行判断用户权限。