Javascript 为promise连锁店导出快速路线方法的最佳方式?

Javascript 为promise连锁店导出快速路线方法的最佳方式?,javascript,node.js,express,es6-promise,es6-class,Javascript,Node.js,Express,Es6 Promise,Es6 Class,我有一个API路由正在被重构,以使用ES6承诺来避免回调地狱。 成功转换为承诺链后,我想将我的.then()函数导出到一个单独的文件中,以保持整洁和清晰 路由文件: 函数文件: 这个很好用。但是,我想做的是将类constructor()函数中声明的函数移动到独立的方法中,这些方法可以引用构造函数实例化的值。那样的话,它读起来就更好了 但是,当我这样做的时候,我会遇到范围界定问题-这个没有定义,等等。正确的方法是什么?ES6是否适合在这里使用,还是应该使用其他结构 原始代码: 路线 导出的函数

我有一个API路由正在被重构,以使用ES6承诺来避免回调地狱。

成功转换为承诺链后,我想将我的
.then()
函数导出到一个单独的文件中,以保持整洁和清晰

路由文件:

函数文件:

这个很好用。但是,我想做的是将类
constructor()
函数中声明的函数移动到独立的方法中,这些方法可以引用构造函数实例化的值。那样的话,它读起来就更好了

但是,当我这样做的时候,我会遇到范围界定问题-
这个
没有定义,等等。正确的方法是什么?ES6是否适合在这里使用,还是应该使用其他结构

原始代码:

路线

导出的函数

备选方案#1:

与使用ES6类不同,执行相同行为的另一种方法是导出一个匿名函数,以稍微清理代码,如下所述:

函数文件:

虽然这并不能避免像我最初想要的那样,用
this.someFn()…
标记每个方法,但它确实在路由文件中采取了额外的步骤-这样做可以避免我必须为这些方法分配特定的命名空间

路由文件

当POST请求命中路由时,函数被重置以反映每个新的
req
res
对象,并且
this
关键字显然绑定到每个导入方法中的POST路由回调

重要提示:不能使用此方法导出箭头函数。导出的函数必须是传统的匿名函数。下面是为什么,per在同一个帖子上的评论:

值得注意的是,这是有效的,因为当直接调用函数时,函数中的
this
是全局范围(不以任何方式绑定)

备选方案2:

另一个选项,由以下人员提供:

我要找的,真的,是一个实验性的特征

有一个建议允许您省略构造函数()并直接将赋值放在具有相同功能的类作用域中,但我不建议使用它,因为它是高度实验性的

但是,仍然有一种方法可以将这些方法分开:

或者,您可以始终使用.bind,它允许您在原型上声明方法,然后将其绑定到构造函数中的实例。这种方法具有更大的灵活性,因为它允许从类外部修改方法

根据Bergi的例子:

显然,这与我最初所寻找的更为一致,因为它增强了导出代码的整体可读性。,但这样做需要像我最初那样为routes文件中的新类分配名称空间:

let SubmitRouteFunctions = require('./functions/submitFunctions.js');
let fn = new SubmitRouteFunctions(req, res);

Promise.all([fn.redundancyCheck, fn.getLocationInfo])
       .then(...)
建议/实验功能:

这不是我真正的驾驶室,但是根据,目前有一个第2阶段的建议(),它试图将“类实例字段”添加到下一个ES规范中

“类实例字段”描述要存在于上的属性 类的实例(并且可以选择包括初始值设定项 上述属性的表达式)

据我所知,通过允许附加到
类的方法引用自身的每个实例化,这将完全解决这里描述的问题。因此,
这个问题将消失,并且可以选择自动绑定方法

我(有限)的理解是,箭头函数将用于实现这一点,如下所示:

  class SomeClass {
      constructor() {...}
      someMethod (val) => {
        // Do something with val
        // Where 'this' is bound to the current instance of SomeClass
      }
    }

显然,现在可以使用Babel编译器来实现这一点,但这显然是实验性的和有风险的。另外,在本例中,我们尝试在Node/Express中执行此操作,这几乎是一个没有实际意义的问题:)

这是一个非常好的配色方案,但您能否将代码作为文本而不是图像包含?哈哈。做了,做了。有屏幕在手,认为它们可能更容易阅读。我要说的是,你在所有地方使用的箭头功能都是合适的ES6解决方案。当然,您也可以在路由器代码上进行所有绑定,但这并不能为您带来任何好处。理想情况下,我希望将其移动到类似
constructor(req,res){…}resetRedundantID(…args){…}
等的位置,而不是将其全部保存在构造函数中。虽然效果很好,但这会使它更容易阅读:)就个人而言,我想我更喜欢方法1。尽管这不允许您将方法与
this.method=…
调用分开,并且在导出的文件中可读性较差,但它使Express route中的承诺链干净、清晰、简洁——这是我的首要目标。它还使用更少的代码,因为它完全避免了
构造函数()
函数,不需要多行
.bind(this)
声明,并且不必将导出的方法绑定到它们自己的命名空间。思想?
module.exports = function (req, res) {

    this.initialData = {
      answers    : req.body.responses,
      coreFit    : req.body.coreFit,
      secondFit  : req.body.secondFit,
      modules    : req.body.modules,
    };

    this.newId = shortid.generate();
    this.visitor = ua('UA-83723251-1', this.newId, {strictCidFormat: false}).debug();
    this.clientIp = requestIp.getClientIp(req);

    this.redundancyCheck = mongoose.model('Result').findOne({quizId: this.newId});
    this.getLocationInfo = request.get('http://freegeoip.net/json/' + this.clientIp).catch((err) => err);

    this.resetRedundantID = ([mongooseResult, clientLocationPromise]) => {
        if (mongooseResult != null) {
          console.log('REDUNDANT ID FOUND - GENERATING NEW ONE')
          this.newId = shortid.generate();
          this.visitor = ua('UA-83723251-1', this.newId, {strictCidFormat: false});
          console.log('NEW ID: ', this.newId);
        };
        return clientLocationPromise.data;
      }

    this.constructSurveyResult = (clientLocation) => {
        let additionalData = {quizId: this.newId, location: clientLocation};
        return Object.assign({}, this.initialData, additionalData);
      }

    this.storeResultInDB = (newResult) => mongoose.model('Result').create(newResult).then((result) => result).catch((err) => err);

    this.redirectToUniqueURL = (mongooseResult) => {
      let parsedId = '?' + queryString.stringify({id: mongooseResult.quizId});
      let customUrl = 'http://explore-your-fit.herokuapp.com/results' + parsedId;
      res.send('/results' + parsedId);
    }
}
.post((req, res) => {
          require('./functions/submitFunctions_2.js')(req, res);

          Promise.all([redundancyCheck, getLocationInfo])
                 .then(resetRedundantID)
                 .then(constructSurveyResult)
                 .then(storeResultInDB)
                 .then(redirectToUniqueURL)
                 .catch((err) => {
                   console.log(err);
                   res.send("ERROR SUBMITTING YOUR RESULT: ", err);
                 });
      })
module.exports = class SomeClass {

  constructor() {
    this.someMethod= this.someMethod.bind(this);
    this.someOtherMethod= this.someOtherMethod.bind(this);
    …
  }

  someMethod(val) {
    // Do something with val
  }

  someOtherMethod(val2) {
    // Do something with val2
  }
}
let SubmitRouteFunctions = require('./functions/submitFunctions.js');
let fn = new SubmitRouteFunctions(req, res);

Promise.all([fn.redundancyCheck, fn.getLocationInfo])
       .then(...)
  class SomeClass {
      constructor() {...}
      someMethod (val) => {
        // Do something with val
        // Where 'this' is bound to the current instance of SomeClass
      }
    }