【问题标题】:JS Currying a static functionJS Currying 一个静态函数
【发布时间】:2019-03-06 04:52:34
【问题描述】:

我有一段类似下面的代码。

// controller.js
class Controller {
    static easyPost = _post(EasyAuth, EasyValidate, EasyHandle);

    static hardPost = _post(HardAuth, HardValidate, HardHandle);

    static _post(auth, validate, handle) {
        return (req) => {
            if (auth(req) && validate(req))
                handle(req);
        }
    }
}

module.exports = Controller;

//controllermapper.js
const Controller = require("./controller");

class ControllerMapper {
    static map(req) {
        switch (req.path) {
            case "/easyPost":
                Controller.easyPost(req);
                break;
            case "/hardPost":
                Controller.hardPost(req);
                break;
        }
    }
}

背后的想法是我可以通过柯里化创建easyPosthardPost。因为它们的总体流程非常相似。

但是,当我尝试将代码推送到 Google Cloud Function 时。它会引发类似

的错误
> Detailed stack trace: /user_code/controller.js:6
>     static easyPost = _post(EasyAuth, EasyValidate, EasyHandle);
>                     ^
> 
> SyntaxError: Unexpected token =

我应该怎么做才能解决这个问题?


编辑

我把代码改成了

// controller.js
class Controller {
    static easyPost(req) {
        Controller._post(EasyAuth, EasyValidate, EasyHandle)(req);
    }

    static hardPost(req) {
        Controller._post(HardAuth, HardValidate, HardHandle)(req);
    }

    static _post(auth, validate, handle) {
        return (req) => {
            if (auth(req) && validate(req))
                handle(req);
        }
    }
}

如果这是一个好的做法,可以对此发表任何评论吗?

【问题讨论】:

  • 这是一个语法错误。您不能在这样的类中分配变量。你确定这门课是你想要的吗?
  • 如果没有,我应该使用什么。我来自 Java 背景,我只想要一些 public static 方法,如果这有意义的话。

标签: javascript class google-cloud-platform google-cloud-functions currying


【解决方案1】:

目前可以使用

class Controller {
    static _post(auth, validate, handle) {
        return req => {
            if (auth(req) && validate(req)) handle(req);
        };
    }
}
Controller.easyPost = _post(EasyAuth, EasyValidate, EasyHandle);
Controller.hardPost = _post(HardAuth, HardValidate, HardHandle);

有一个第 3 阶段的提案,您编写的代码可以正常工作 - https://github.com/tc39/proposal-static-class-features/

写得不太好 - 你需要指定Controller._post,如下所示

class Controller {
    static _post(auth, validate, handle) {
        return (req) => {
            if (auth(req) && validate(req))
                handle(req);
        }
    }
    static easyPost = Controller._post(EasyAuth, EasyValidate, EasyHandle);
    static hardPost = Controller._post(HardAuth, HardValidate, HardHandle);
}

注意:你可以在 babeljs 中启用它,但它在 babel 的 stage-2 中

关于您更新的代码 - 您仍然需要致电 Controller._post 而不仅仅是 _post

class Controller {
    static easyPost(req) {
        return Controller._post(EasyAuth, EasyValidate, EasyHandle)(req);
    }

    static hardPost(req) {
        return Controller._post(HardAuth, HardValidate, HardHandle)(req);
    }

    static _post(auth, validate, handle) {
        return (req) => {
            if (auth(req) && validate(req))
                handle(req);
        }
    }
}

为了证明您必须使用 Controller._post,这里是您的代码的精简版本

class Controller {
    static succeeds(req) {
        return Controller._post()(req);
    }

    static fails(req) {
        return _post()(req);
    }

    static _post() {
        return (req) => {
          	return `got ${req}`;
        }
    }
}
console.log(Controller.succeeds('ok'))
console.log(Controller.fails('ok'))

最后,你不必使用Controller._post的代码版本

const post = (auth, validate, handle) => (req) => {
    if (auth(req) && validate(req)) {
        handle(req);
    }
};
class Controller {
    static easyPost(req) {
        return post(EasyAuth, EasyValidate, EasyHandle)(req);
    }

    static hardPost(req) {
        return post(HardAuth, HardValidate, HardHandle)(req);
    }

}
module.exports = Controller;

现在post 也是私有的

不过,如果我要写这篇文章,我会这样做

const post = (auth, validate, handle) => (req) => {
    if (auth(req) && validate(req)) {
        handle(req);
    }
};
class Controller {
}
Controller.easyPost = post(EasyAuth, EasyValidate, EasyHandle);
Controller.hardPost = post(HardAuth, HardValidate, HardHandle);
module.exports = Controller;

或者,如果这就是控制器的全部内容

const post = (auth, validate, handle) => (req) => {
    if (auth(req) && validate(req)) {
        handle(req);
    }
};
module.exports = {
    easyPost: post(EasyAuth, EasyValidate, EasyHandle),
    hardPost: post(HardAuth, HardValidate, HardHandle)
};

【讨论】:

  • 感谢您的评论。稍后我将详细说明您的评论。但是我用我的“解决方案”编辑了我的问题,你能不能也给我一个快速的评论?非常感谢您。
  • 更新后的代码无法执行您想要的操作-一方面easyPosthardPost 不会在更新后的代码中返回任何内容-您仍然需要调用@ 987654336@不是_post
  • 但是当我打电话给Controller.easyPost(req) 时,它确实通过了。
  • 是吗?你确定吗?用Controller._post_post 检查最终的、可执行的、演示...
  • @Man-KitYau - 如果您可以发布不使用 Controller._post 但仍能正确执行的代码版本,我会非常感兴趣(除非您已移动 _post当然课外
猜你喜欢
  • 1970-01-01
  • 2022-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
相关资源
最近更新 更多