JS从ES6开始就有

小说:早知道这些事,我们就可以少当几次傻逼作者:伯王马更新时间:2019-03-26字数:14051

但在此刻此地,他柳如叶最大,手下的一看上司不让开火,当然只能停止了射击,只见那两个鬼子一看柳如叶对他们伸出来小手指,便气急败坏的“哇哇”乱叫着冲上来,两把亮闪闪的东洋刀一左一右朝柳如叶的脑门子劈下来,那势头简直是要把柳如叶生生的劈成两半啊。

妈妈要重视,宝宝打呼噜,不是睡得香!

附近的空气立刻不断震动起来,只是纵然四周的人捂住了耳朵闭上了眼睛但是这一招术还是让很多麻痹起来,也救了已经失去了须佐能乎保护眼看就要被挖出眼睛的宇智波佐助一命。
按照林媚儿心中的想法,她放弃女人天生的嫉妒。为了让事情得到圆满地解决,她甚至愿意与众女一同分享雪飞鸿。一同分享一个爱人,她为大家付出了那么多,可是。大家却没有为她付出过任何东西。林媚儿心中对于珠宝司空见惯,远远没有普通女孩子那么看重。海洋之心虽然是绝世之珍,可她更愿意把这串价值连城地宝贝,转赠给自己最敬重的姐姐。

“对,就是等价交换,你问我一个问题,我回答你,不会敷衍了事,那么我也会问你一个问题,你也必须说实话如何?”刘皓说道:“当然为了公平,你问什么我也会问那个范畴的事情,你问我机密我也会问你机密,你问其他我也会问你其他,不会占你这个舰长的便宜。”

Koa

在Spring中Controller长这样

@Controller
public class HelloController{
    @RequestMapping("/hello")
    String hello() {
        return "Hello World";  
    }
}

还有Python上的Flask框架

@app.route("/hello")
def hello():
    return "Hello World"

两者都用decorator来控制路由,这样写的好处是更简洁、更优雅、更清晰。

反观Express或Koa上的路由

router.get("/hello", async ctx => {
    ctx.body = "Hello World"
})

完全差了一个档次

JS从ES6开始就有Decorator了,只是浏览器和Node都还没有支持。需要用babel-plugin-transform-decorators-legacy转义。

Decorator基本原理

首先需要明确两个概念:

  1. Decorator只能作用于类或类的方法上
  2. 如果一个类和类的方法都是用了Decorator,类方法的Decorator优先于类的Decorator执行

Decorator基本原理:

@Controller
class Hello{

}

// 等同于

Controller(Hello)

Controller是个普通函数,target为修饰的类或方法

// Decorator不传参
function Controller(target) {

}

// Decorator传参
function Controller(params) {
    return function (target) {

    }
}

如果Decorator是传参的,即使params有默认值,在调用时必须带上括号,即:

@Controller()
class Hello{

}

如何在Koa中使用Decorator

我们可以对koa-router中间件进行包装

先回顾一下koa-router基本使用方法:

var Koa = require("koa");
var Router = require("koa-router");

var app = new Koa();
var router = new Router();

router.get("/", async (ctx, next) => {
  // ctx.router available
});

app
  .use(router.routes())
  .use(router.allowedMethods());

再想象一下最终目标

@Controller({prefix: "/hello"})
class HelloController{
    @Request({url: "/", method: RequestMethod.GET})
    async hello(ctx) {
        ctx.body = "Hello World"
    }
}

类内部方法的装饰器是优先执行的,我们需要对方法重新定义

function Request({url, method}) {
    return function (target, name, descriptor) {
        let fn = descriptor.value
        descriptor.value = (router) => {
            router[method](url, async(ctx, next) => {
                await fn(ctx, next)
            })
        }
    }
}

对RequestMethod进行格式统一

const RequestMethod = {
    GET: "get",
    POST: "post",
    PUT: "put",
    DELETE: "delete"
}

Controller装饰器需将Request方法添加到Router实例并返回Router实例

import KoaRouter from "koa-router"

function Controller({prefix}) {
    let router = new KoaRouter()
    if (prefix) {
        router.prefix(prefix)
    }
    return function (target) {
        let reqList = Object.getOwnPropertyDescriptors(target.prototype)
        for (let v in reqList) {
            // 排除类的构造方法
            if (v !== "constructor") {
                let fn = reqList[v].value
                fn(router)
            }
        }
        return router
    }
}

至此,装饰器基本功能就完成了,基本使用方法为:

import {Controller, Request, RequestMethod} from "./decorator"

@Controller({prefix: "/hello"})
export default class HelloController{
    @Request({url: "/", method: RequestMethod.GET})
    async hello(ctx) {
        ctx.body = "Hello World"
    }
}

在App实例中同路由一样use即可。

原文地址:用Decorator控制Koa路由
我的博客:Bougie的博客

编辑:王密开华

发布:2019-03-26 06:25:56

当前文章:http://leetaemin.cn/play/8r65ulaxhr.html

家长观念中的误区 怎么确定家中的风水财位? 中国首位女科学家屠呦呦获诺贝尔奖 解脱心灵的枷锁——释放 【情感咨询】执迷不悟单恋的男孩 修持戒定慧来开悟明智和去除烦恼 没错,我就是个坏男人 你越来越普通,是因为过度的羞耻感

58178 23497 61884 70429 23865 60761 18612 17404 76488 52919 19625 18943 63718 83751 52045 97757 52063 48418 71315 97603

我要说两句: (0人参与)

发布