zoukankan      html  css  js  c++  java
  • Koa入门和源码分析

    1:koa入门
    初始化文件 npm init
    安装koa  npm install koa –save
    (1)Hello world练习
    const Koa = require("koa");
    
    const app = new Koa(); //app是应用的起步
    app.use(async(ctx,next) =>{  //ctx封装的是request 和 response
        ctx.body = "hello world"  //next封装的是一下个中间件
    })
    app.listen(3000);
    
    2:原理封装实现
    (1)	Hello world浅层原理实现
    const http = require('http')
    const server =  http.createServer((req,res)=>{
        res.writeHead(200)
        res.end("hello world ")
    })
    server.listen(8088)
     
    //封装use,listen方法
    const Woa = require('./application')
    const app = new Woa()
    app.use((req,res)=>{
        res.writeHead(200)
        res.end("hello server")
    })
    
    app.listen(8088)
    
    const http = require('http')
    class Application{
     
        constructor(){
            this.callback = ()=>{}
        }
        use(callback){
            this.callback = callback
        }
        listen(...args){
            const server = http.createServer((req,res)=>{
                this.callback(req,res)
                server.listen(...args)
            })
        }
    }
    module.exports = Application
    
    (2)	context封装
    构建ctx 
    挂载request和response对象
    Ctx.body = xx 就可以修改相应 如何做到
    Js的getter 和setter
    
    
    (3)同步的compose实现原理(中间件)
    function add(x,y){
      return x+y
    }
    function double(z){
      return z*2
    }
    const res1 = add(1,2)
    const res2 = double(res1)
    console.log(res2)
    
    const res3 = double(add(1,2))
    console.log(res3)
    const middlewares = [add, double]
    let len = middlewares.length
    function compose(midds){
      return (...args)=>{
        // 初始值
        let res = midds[0](...args)
        for(let i=1;i<len;i++){
          res = midds[i](res)
        }
        return res
      }
    }
    const fn = compose(middlewares)
    const res = fn(1,2)
    console.log(res)
    
    (3)	异步有序执行中间件(next实现原理递归)
    
    async function fn1(next){
      console.log('fn1')
      await next()
      console.log('end fn1')
    }
    
    async function fn2(next){
      console.log('fn2')
      await delay()
      await next()
      console.log('end fn2')
    }
    function fn3(next){
      console.log('fn3')
    }
    
    function delay(){
      return new Promise((reslove,reject)=>{
        setTimeout(()=>{
          reslove()
        },2000)
      })
    }
    
    function compose (middlewares){
      return function(){
        return dispatch(0)
        function dispatch(i){
          let fn = middlewares[i]
          if(!fn){
            return Promise.resolve()
          }
          return Promise.resolve(fn(function next(){
            return dispatch(i+1)
          }))
        }
      }
    }
    
    const middlewares = [fn1,fn2,fn3]
    const finalFn = compose(middlewares)
    finalFn()
    
    
    
    (4)	完整实现简单的koa
    const http = require('http')
    let request = {
      get url(){
        return this.req.url
      }
    }
    let response = {
      get body(){
        return this._body
      },
      set body(val){
        this._body = val
      }
    }
    
    let context = {
      get url(){
        return this.request.url
      },
      get body(){
        return this.response.body
      },
      set body(val){
        this.response.body = val
      }
    }
    class Application {
      constructor(){
        // this.callback = ()=>{}
        this.context = context
        this.request = request
        this.response = response
        this.middlewares = []
      }
      use(callback){
        this.middlewares.push(callback)
        // this.callback = callback
      }
      compose (middlewares){
        return function(context){
          return dispatch(0)
          function dispatch(i){
            let fn = middlewares[i]
            if(!fn){
              return Promise.resolve()
            }
            return Promise.resolve(fn(context,function next(){
              return dispatch(i+1)
            }))
          }
        }
      }
      listen(...args){
          const server = http.createServer(async(req,res)=>{
          let ctx = this.createCtx(req,res)
          const fn = this.compose(this.middlewares)
          await fn(ctx)
          ctx.res.end(ctx.body)
          // this.callback(req,res)
        })
        server.listen(...args)
      }
      createCtx(req, res){
        let ctx = Object.create(this.context)
        ctx.request = Object.create(this.request)
        ctx.response = Object.create(this.response)
        ctx.req = ctx.request.req = req
        ctx.res = ctx.response.res = res
        return ctx
      }
    }
    module.exports = Application
    
    //server.js
    const Woa = require('./application')
    const app = new Woa()
    function delay(){
      return new Promise((reslove,reject)=>{
        setTimeout(()=>{
          reslove()
        },2000)
      })
    }
    
    app.use(async (ctx,next)=>{
      ctx.body = '1'
      await next()
      ctx.body += '2'
    })
    app.use(async (ctx,next)=>{
      ctx.body += '3'
      await delay()
      await next()
      ctx.body += '4'
    })
    app.use(async (ctx,next)=>{
      ctx.body += '5'
    })
    // app.use((req, res)=>{
    //   res.writeHead(200)
    //   res.end('hello imooc')
    // })
    app.listen(9092,()=>{
      console.log('server runing on port 9092')
    })
    

      

  • 相关阅读:
    [BZOJ5339] [TJOI2018]教科书般的亵渎
    拉格朗日插值法
    [LOJ#2340] [WC2018] 州区划分
    [洛谷4609] [FJOI2016]建筑师
    [CF960G] Bandit Blues
    [BZOJ2115] [WC2011] Xor
    [Codeforces 809E] Surprise me!
    无需AutoCAD,用C#生成DWG文件
    扩展方法的几点总结
    RedirectStandardOutput
  • 原文地址:https://www.cnblogs.com/love-life-insist/p/10254425.html
Copyright © 2011-2022 走看看