Koa和Express相关学习记录

146 阅读1分钟

洋葱模型

redux Express Koa在处理中间件的时候,逻辑类似,都用到了compose方法

    compose(ctx) {
        let middlewares = this.middlewares
        let idx = -1;
        function dispatch(i) {
            // 没有中间件直接成功
            if (i <= idx) return Promise.reject(new Error('next() call multiple times'))
            if (i === middlewares.length) return Promise.resolve()
            let fn = middlewares[i];
            idx = i
            //  我们将用户的函数包装了promise
            // 而且是一个链式的调用
            try {
                // 可能用户提供的是一个普通的函数,此时没办法通过promise 来进行捕获,所以要直接try catch
                return Promise.resolve(fn(ctx, () => dispatch(i + 1)))
            } catch (err) {
                return Promise.reject(err)
            }
        }
        return dispatch(0)
    }
    handleRequest = (req, res) => {
        // 每次请求都是独立的, 不会出现 不同的请求 复用属性
        const ctx = this.createContext(req, res)

        res.statusCode = 404;

        this.compose(ctx).then(() => {
            let body = ctx.body;
            if (typeof body === 'string' || Buffer.isBuffer(body)) {
                res.end(body)
            } else {
                res.end('Not Found')
            }
        }).catch(err => {
            this.emit('error', err)
        })

    }

每次请求过来时,会走handleRequest方法,然后就通过dispatch(0)触发整个调用链