koa学习二

之前完成了request的封装,现在封装response对象,并挂载response对象到ctx上

applaction.js

let http = require('http')
let context = require('./content')
let request = require('./request')
let response = require('./response')

class Koa {
    constructor () {
        // 默认回调函数
        this.callbackFn = () => {}
        // 通常将外部变量挂载到this对象上,后边使用this获取
        this.context = context
        this.request = request
        this.response = response
    }
    /**
     * @description 创建服务
     */
    listen () {
        // 创建服务
        let server = http.createServer(this.handleRequest())
        // 将创建服务的传入的参数直接传给server
        server.listen(...arguments)
    }
    use (fn) {
        this.callbackFn = fn
    }
    /**
     * @description 监听服务函数
     * @return {Function} fn 一个箭头函数(不会有this指向问题)
     */
    handleRequest () {
        // 如果说直接把函数作为参数在创建服务的时候this会出现问题,
        // 当我们使用箭头函数的时候,this可以保证是我们的实例
        return (req, res) => {
            // 创建上下文对象
            let ctx = this.createContext(req, res)
            // 处理异步的问题
            Promise.resolve(this.callbackFn(ctx))
                .then(() => res.end(ctx.body))

        }
    }
    /**
     * @description 创建ctx对象
     */
    createContext (req, res) {
        // 为了防止修原来的request,response对象,我们创建对象

        // 创建上下文
        let ctx = Object.create(this.context)
        // 创建request
        ctx.request = Object.create(this.request)
        ctx.req = ctx.request.req = req

        // 创建response
        ctx.response = Object.create(this.response)
        ctx.res = ctx.response.res = res
        // 创建完成,返回对象
        return ctx
    }
}

module.exports = Koa

content.js

/**
 * @description proto koa封装的ctx对象
 */

 // context 代理request和response属性
 // 设置getter和setter
 let proto = {}
/**
 * @description 代理函数
 * @param {string} property 需要代理的属性
 * @param {string} name 需要拿到的值
 * 
 * 使用方式:
 *   ctx.query = ctx.request.query
 *   让proto代理requ上的query属性
 *   delateGetter('request', 'query')
 */
 function delateGetter (property, name) {
    //  __defineGetter__ 不推荐使用
    // 该__defineGetter__方法将对象的属性绑定到要在查找该属性时调用的函数。
    //  语法:obj .__ defineGetter __(prop,func)
    // prop
    // 一个字符串,包含要绑定到给定函数的属性的名称。
    // func
    // 要绑定到指定属性的查找的函数。

     proto.__defineGetter__(name, function () {
         return this[property][name]
     })
 }

// proto === ctx
//  ctx.query = ctx.request.query
/**
 * @description 设置参数
 * @param {string} property 
 * @param {sgring} name 
 */
function delateSetter (property, name) {
    proto.__defineSetter__(name, function (val) {
        this[property][name] = val
    })
}
// 让proto代理requ上的query属性
delateGetter('request', 'query')
delateGetter('request', 'method')
delateGetter('response', 'body')

// 设置代码
delateSetter('response', 'body')
module.exports = proto

response.js

// 自己封装的 response 对象
let response = {
    get body () {
        return this._body
    },
    set body (body) {
        this._body = body
    }
}

module.exports = response

总结

到了这里就完成了response对象的封装和挂载,下一接处理next回调

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值