看教程下面这么写,中间件执行不了了,为什么要把类的属性转化成数组呢

来源:12-4 [第 5 次迭代] 增加用户会话保持与数据删除功能

慕雪3661411

2018-09-08

target[key] = isArray(target[key]) target[key].unshift(mid) 这样写的花我发现中间件执行不了了,这样写的目的是?
写回答

1回答

Scott

2018-09-09

const Router = require('koa-router')
const { resolve } = require('path')
const _ = require('lodash')
const glob = require('glob')
const R = require('ramda')
const symbolPrefix = Symbol('prefix')
const routerMap = new Map()
const isArray = c => _.isArray(c) ? c : [c]
export class Route {
  constructor (app, apiPath) {
    this.app = app
    this.apiPath = apiPath
    this.router = new Router()
  }
  init () {
    glob.sync(resolve(this.apiPath, './**/*.js')).forEach(require)
    for (let [conf, controller] of routerMap) {
      console.log(controller)
      const controllers = isArray(controller)
      let prefixPath = conf.target[symbolPrefix]
      if (prefixPath) prefixPath = normalizePath(prefixPath)
      const routerPath = prefixPath + conf.path
      this.router[conf.method](routerPath, ...controllers)
    }
    this.app.use(this.router.routes())
    this.app.use(this.router.allowedMethods())
  }
}
const normalizePath = path => path.startsWith('/') ? path : `/${path}`
const router = conf => (target, key, descriptor) => {
  conf.path = normalizePath(conf.path)
  routerMap.set({
    target: target,
    ...conf
  }, target[key])
}
export const controller = path => target => (target.prototype[symbolPrefix] = path)
export const get = path => router({
  method: 'get',
  path: path
})
export const post = path => router({
  method: 'post',
  path: path
})
export const put = path => router({
  method: 'put',
  path: path
})
export const del = path => router({
  method: 'delete',
  path: path
})
export const use = path => router({
  method: 'use',
  path: path
})
export const all = path => router({
  method: 'all',
  path: path
})
const decorate = (args, middleware) => {
  let [ target, key, descriptor ] = args
  target[key] = isArray(target[key])
  target[key].unshift(middleware)
  return descriptor
}
const convert = middleware => (...args) => decorate(args, middleware)
export const auth = convert(async (ctx, next) => {
  console.log('ctx.session.user')
  console.log(ctx.session.user)
  if (!ctx.session.user) {
    return (
      ctx.body = {
        success: false,
        code: 401,
        err: '登录信息失效,重新登录'
      }
    )
  }
  await next()
})
export const admin = roleExpected => convert(async (ctx, next) => {
  const { role } = ctx.session.user
  console.log('admin session')
  console.log(ctx.session.user)
  if (!role || role !== roleExpected) {
    return (
      ctx.body = {
        success: false,
        code: 403,
        err: '你没有权限,来错地方了'
      }
    )
  }
  await next()
})
export const required = rules => convert(async (ctx, next) => {
  let errors = []
  const checkRules = R.forEachObjIndexed(
    (value, key) => {
      errors = R.filter(i => !R.has(i, ctx, ctx.request[key]))(value)
    }
  )
  checkRules(rules)
  if (errors.length) {
    ctx.body = {
      success: false,
      code: 412,
      err: `${errors.join(',')} is required`
    }
  }
  await next()
})


可以比对下,有没有少写 descriptor 之类的,这里的 isArray 和 unshift 很简单,就是把当前被  convert 的中间件插入到中间件数组头部,这块要结合装饰器来理解,target key descriptor 都是装饰器相关的,这样组织代码会稍微难懂晦涩一些。

0
0

Koa2框架从0开始构建预告片网站

Koa2+MongoDB+Parcel+Puppeteer+AntDesign快速搭建预告片网站

751 学习 · 362 问题

查看课程