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

2019-06-16  本文已影响0人  DreamNeverDie

框架实现的主文件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);

上一篇 下一篇

猜你喜欢

热点阅读