美文网首页
2019-06-16 手写简易koa框架 (开课吧)

2019-06-16 手写简易koa框架 (开课吧)

作者: DreamNeverDie | 来源:发表于2019-06-16 23:36 被阅读0次

    框架实现的主文件kkb.js文件,这里将Koa起名为Kkb

    const http = require("http");
    const context = require("./context");
    const request = require("./request");
    const response = require("./response");
    
    // koa实现主文件
    class Kkb {
    
        constructor(){
            this.middlewares = [];
        }
    
      listen(...args) {
        http
          .createServer(async (req, res) => {
            //   创建上下文对象
            const ctx = this.createContext(req,res);
            // 将middlewares变成一个
            const fn = this.compose(this.middlewares)
            await fn(ctx)
            // 给用户返回数据
            res.end(ctx.body);
          })
          .listen(...args);
      }
      use(mid) {
          this.middlewares.push(mid);
      }
      createContext(req, res){
        const ctx = Object.create(context);
        ctx.request = Object.create(request);
        ctx.response = Object.create(response);
    
        ctx.req = ctx.request.req = req;
        ctx.res = ctx.response.res = res;
    
        return ctx;
      }
      compose(middlewares) {
        return function(ctx) {
          return dispatch(0);
          // 执行第0个
          function dispatch(i) {
            let fn = middlewares[i];
            if (!fn) {
              return Promise.resolve();
            }
            return Promise.resolve(
              fn(ctx, function next() {
                // promise完成后,再执行下一个
                return dispatch(i + 1);
              })
            );
          }
        };
      }
    }
    
    module.exports = Kkb;
    

    框架依赖文件context.js

    module.exports = {
        get url() {
            return this.request.url;
        },
        get body(){
            return this.response.body;
        },
        set body(val){
            this.response.body = val;
        }
    }
    

    框架依赖文件request.js

    module.exports = {
        get url() {
            return this.req.url;
        }
    }
    

    框架依赖文件response.js

    module.exports = {
        get body() {
            return this._body;
        },
        set body(val) {
            this._body = val;
        }
    }
    

    最后是使用框架的客户端文件app.js

    // 我们的kkb使用
    const Kkb = require("./kkb");
    const app = new Kkb();
    
    // app.use(ctx => {
    //     ctx.body = 'hello kkb.js'
    // //   res.writeHead(200, {
    // //     "Content-Type": "application/json"
    // //   });
    
    //   // res.statusCode = 200;
    // //   res.end(JSON.stringify({ name: "Jerry" }));
    // });
    
    function delay() {
      return new Promise((reslove, reject) => {
        setTimeout(() => {
          reslove();
        }, 1000);
      });
    }
    
    app.use(async (ctx, next) => {
      ctx.body = "1";
      setTimeout(() => {
        ctx.body += "2";
      }, 2000);
      await next();
      ctx.body += "3";
    });
    
    app.use(async (ctx, next) => {
      ctx.body += "4";
      await delay();
      await next();
      ctx.body += "5";
    });
    
    app.use(async (ctx, next) => {
      ctx.body += "6";
    });
    
    app.listen(3000);
    
    // const http = require("http");
    
    // http
    //   .createServer((req, res) => {
    //     res.writeHead(200);
    //     res.end("hi kaikeba");
    //   })
    //   .listen(3000);
    
    // const Koa = require('koa')
    // const app = new Koa()
    // const {createReadStream} = require('fs')
    
    // // 模块化/简化
    // // 优雅api
    // // 中间件机制
    // app.use(async (ctx, next) => {
    //     if (ctx.path === '/favicon.ico') {
    //         ctx.body = createReadStream('./favicon.ico')
    //     } else {
    //         await next();
    //     }
    // })
    
    // app.use(ctx => {
    // ctx.body = 'hi kaikeba'
    // })
    
    // app.listen(3000);
    
    

    相关文章

      网友评论

          本文标题:2019-06-16 手写简易koa框架 (开课吧)

          本文链接:https://www.haomeiwen.com/subject/tyinfctx.html