75 # koa 基本逻辑实现以及属性的扩展

简介: 75 # koa 基本逻辑实现以及属性的扩展

准备工作

新建自己的 kaimo-koa 文件夹,结构如下:

  • lib
  • application.js:创建应用
  • context.js:上下文
  • request.js:koa 中自己实现的 request 的对象
  • response.js:koa 中自己实现的 response 的对象
  • package.json:里面需要注意 main 字段,我们需要将 lib/application.js 作为入口
{
    "name": "kaimo-koa",
    "version": "1.0.0",
    "description": "",
    "main": "lib/application.js",
    "directories": {
        "lib": "lib"
    },
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC"
}

ctx 是什么东西?

ctx 中整合了 request 和 response,req 以及 res

  • koa 自己实现的 request 和 response
  • http 原生的 req 以及 res

ctx.request.req.urlctx.req.url 是等价的

ctx.path 就是去 ctx.request.path 上取的,ctx.request 内部使用了 url 模块进行解析

代码实现基本的逻辑以及属性的扩展

application.js:创建应用

const EventEmitter = require("events");
const http = require("http");
const context = require("./context");
const request = require("./request");
const response = require("./response");
console.log("kaimo-koa---->");
class Application extends EventEmitter {
    constructor() {
        super();
        // 防止多个实例共享 context request response 需要进行拷贝
        this.context = Object.create(context);
        this.request = Object.create(request);
        this.response = Object.create(response);
    }
    use(callback) {
        this.callback = callback;
    }
    // 创建一个上下文
    createContext(req, res) {
        // 每次请求都应该是一个全新的 context,需要拷贝
        let ctx = Object.create(this.context);
        // 上下文中有一个 request 对象,是自己封装的
        ctx.request = Object.create(this.request);
        // 上下文中还有一个 req 属性 指代的是原生的 req,自己封装的 request 对象上有 req 属性
        ctx.req = ctx.request.req = req;
        return ctx;
    }
    handleRequest(req, res) {
        const ctx = this.createContext(req, res);
        this.callback(ctx);
    }
    listen(...args) {
        const server = http.createServer(this.handleRequest.bind(this));
        server.listen(...args);
    }
}
module.exports = Application;

request.js:koa 中自己实现的 request 的对象,进行属性扩展

const url = require("url");
const request = {
    // 属性访问器的方式 ctx.request.url 就会执行 url()
    get url() {
        // this 就是 ctx.request
        return this.req.url;
    },
    get path() {
        return url.parse(this.req.url).pathname;
    },
    get query() {
        return url.parse(this.req.url).query;
    }
    // ... 可以自己添加其他的扩展属性
};
module.exports = request;

编写 demo.js 测试

const Koa = require("./kaimo-koa");
const app = new Koa();
app.use(async (ctx, next) => {
    ctx.body = "Hello kaimo Koa";
    console.log("url---->", ctx.request.url);
    console.log("path---->", ctx.request.path);
    console.log("query---->", ctx.request.query);
});
app.on("error", (err) => {
    console.log(err);
});
app.listen(3000);

启动服务后访问 http://localhost:3000/kaimo?a=313

nodemon demo.js

目录
相关文章
|
5月前
|
前端开发 API
vue3【详解】选项式 API 实现逻辑复用
vue3【详解】选项式 API 实现逻辑复用
74 1
|
5月前
|
开发框架 前端开发 JavaScript
循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中
循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中
|
7月前
|
JavaScript
Vue定义全局组件的三种方式
Vue定义全局组件的三种方式
50 0
|
设计模式 前端开发 JavaScript
采用「复合模式」构建可复用的 Web 前端组件
在现代 Web 前端开发中,构建可复用、可维护的组件是提高开发效率和代码质量的关键。为了实现这一目标,开发者们一直在寻找合适的设计模式和架构原则。其中,Compound Pattern(复合模式)被广泛应用于构建具有高度复用性和可扩展性的 Web 前端组件。本文将深入探讨 Compound Pattern 的概念、优点和缺点,适用场景,开源实现方案,以及其在知名项目中的应用
4878 1
采用「复合模式」构建可复用的 Web 前端组件
|
JavaScript 测试技术 开发者
vue封装通用组件方法思路
vue封装通用组件方法思路
386 0
|
JavaScript 前端开发
vue的组件化的理解之单独拆分的组件&组件的封装(以el-table组件的二次封装举例)
vue的组件化的理解之单独拆分的组件&组件的封装(以el-table组件的二次封装举例)
283 0
|
JavaScript 前端开发
js对象的创建对象模式和继承模式(上)---构建对象模式
js对象的创建对象模式和继承模式(上)---构建对象模式
134 0
|
JavaScript
Vue——05-01组件的基本使用、全局组件,局部组件、父子组件的区别、注册组件的语法糖以及分离写法
组件的基本使用、全局组件,局部组件、父子组件的区别、注册组件的语法糖以及分离写法
117 0
|
JavaScript
vue父子组件之间的传额外的参数
vue父子组件之间的传额外的参数
vue父子组件之间的传额外的参数
|
XML JSON 前端开发
【Django学习笔记 - 18】:drf请求响应简介、基类(APIView、GenericAPIView)、mixin扩展类与三级视图、视图集与路由
【Django学习笔记 - 18】:drf请求响应简介、基类(APIView、GenericAPIView)、mixin扩展类与三级视图、视图集与路由
215 0
【Django学习笔记 - 18】:drf请求响应简介、基类(APIView、GenericAPIView)、mixin扩展类与三级视图、视图集与路由