【问题标题】:How to keep the value of this when using async.apply? [duplicate]使用 async.apply 时如何保持 this 的值? [复制]
【发布时间】:2019-11-23 15:44:55
【问题描述】:

我正在使用 async.parallel 一次运行 2 个函数,这些函数是从 mongoose 模型上的静态函数运行的。如您所见,我可以通过this 访问模型及其代码中的函数(模型有一个名为 verifyParent 的静态函数):

async.parallel([
      async.apply(content, {slug: slug}),
      async.apply(this.verifyParent, req.body.reply),
    ], (err, result) => {
          //results
});

但是在 this.verifyParent 函数中,如果我尝试使用this,它等于我的 express 应用程序,而不是猫鼬模型。我相信 async.apply 正在这样做,我不知道如何让它保持它通常具有的 this 值。

在 verifyParent 中,我正在尝试查询 mongodb。当我运行this.findOne() 时,它说它不是一个函数,并且看起来这似乎表明它设置了应用程序,而不是模型。

【问题讨论】:

    标签: javascript express mongoose mongoose-schema async.js


    【解决方案1】:

    根据您的问题,this 是模型。

    那你应该把代码改成

    var model = this;
    var verify = function(reply) {
      model.verifyParent(reply);
    };
    async.parallel([
      async.apply(content, {slug: slug}),
      async.apply(verify, req.body.reply),
    ], (err, result) => {
          //results
    });
    

    因为this 关键字是基于上下文的。请参阅Function context 了解更多信息。

    【讨论】:

    • 对不起,我编辑了你的答案而不是我的。删除了我的编辑。
    • @nrgwsth 我发现了他的问题,让他自己去探索。我真的难过他授予你的答案。 ;( PS:bind()返回一个函数,为了更好的编码习惯,应该提取到局部变量。(这也是我试图给他看的)
    【解决方案2】:

    您可以像这样将函数绑定到当前上下文,

    async.parallel([
          async.apply(content, {slug: slug}),
          async.apply(this.verifyParent.bind(this), req.body.reply),
        ], (err, result) => {
              //results
    });
    

    This 是 async.apply 的函数定义,看起来它使用传递的参数调用传递的函数,这就是为什么 this 被设置为父作用域,即 express app。

    所以基本上发生的事情是这样的,

    function apply(fn) {
      return fn();
    }
    
    var model = {
      prop: "world",
      verifyParent: function () {
        console.log("hello", this.prop)
      }
    }
    
    // model context is lost.
    apply(model.verifyParent)
    
    // bind to model explicitly.
    apply(model.verifyParent.bind(model))

    【讨论】:

      【解决方案3】:

      这可以通过以下方式完成:

      使用箭头函数:

      async.parallel([
            async.apply(content, {slug: slug}),
            async.apply(() => this.verifyParent, req.body.reply),
          ], (err, result) => {
                //results
      });
      

      使用硬绑定:

      ...
      function boundedVerifyParent() {
         return this.verifyParent.call(this)
      }
      ...
      async.apply(this.boundedVerifyParent, req.body.reply),
      ...
      

      或者使用bind方法:

      ...
      async.apply(this.verifyParent.bind(this), req.body.reply),
      ...
      

      【讨论】:

        猜你喜欢
        • 2023-04-04
        • 1970-01-01
        • 2018-11-23
        • 1970-01-01
        • 1970-01-01
        • 2013-02-28
        • 2019-07-12
        • 2011-07-22
        • 1970-01-01
        相关资源
        最近更新 更多