Inheritance 在Promise:';超级';这里的关键字是什么?

Inheritance 在Promise:';超级';这里的关键字是什么?,inheritance,scope,ecmascript-6,super,es6-promise,Inheritance,Scope,Ecmascript 6,Super,Es6 Promise,我试图从子实例调用超级方法save() // ImageKeeper.js 'use strict'; module.exports = class ImageKeeper extends FileKeeper { constructor(keeperPath, options) { super(`/${keeperPath}`, options) this.keeperPath = keeperPath; } save(filePath) { retur

我试图从子实例调用超级方法
save()

// ImageKeeper.js
'use strict';

module.exports = class ImageKeeper extends FileKeeper {
  constructor(keeperPath, options) {
    super(`/${keeperPath}`, options)
    this.keeperPath = keeperPath;
  }

  save(filePath) {
    return new Promise((resolve, reject) => {
      this
        .resolvePath(filePath)
        .then(function(fileData) {
          var filePath = fileData[0],
            mime = fileData[1];

          super.save(filePath, mime); // <-- GETTING ERROR HERE
        })
        .catch(function(err) {
          reject(err)
        })
    })
  }
}

// FileKeeper.js
'use strict';

module.exports = class FileKeeper {
  constructor(keeperPath, options) {
    this.storagePath = path.resolve(`${env.paths.storage}${keeperPath}`);
    this.options = options;
  }

  save(filePath, mime) {
    return Promise
      ...
  }
}
如果我移动
super.save(filePath,mime)
save()
方法的开头,它可以工作

我已尝试将上下文绑定到上限:

save(filePath) {
  return new Promise((resolve, reject) => {
    this
      .then((fileData) => { // <-- bind context to upper scope

        super.save(filePath, mime);
阅读,但没有运气

有什么想法吗?多谢各位

环境
看起来您在V8的
super
处理中发现了一个bug;我报告了这个bug,他们将其分为
类型bug
优先级中等
。这是在对它进行了一些详细的调查之后,在我的帖子中证实了我的怀疑,这是一个V8错误

如果您按照您的“我已尝试将上下文绑定到上限”注释使用箭头函数(而不是
函数
函数)(主代码块使用的是
函数
函数,该函数不起作用),则应能起作用

在等待修复时,如果您将该逻辑放入一个方法中,它就会起作用:

someAppropriateName(fileData) {
  var filePath = fileData[0],
    mime = fileData[1];

  super.save(filePath, mime);
}
…并从promise回调调用该方法:

save(filePath) {
  return new Promise((resolve, reject) => {
    this
      .resolvePath(filePath)
      .then(fileData => {                      // **
          this.someAppropriateName(fileData);  // **
      })                                       // **
      .catch(function(err) {
        reject(err)
      })
  })
}
或:

这是因为bug相当模糊:只有在方法中的另一个arrow函数中有一个arrow函数,并且最内部的arrow函数使用外部arrow函数定义的变量或参数时,才会出现bug(使用方法本身的东西是可以的)


不过,还有一些其他注意事项:

  • 如果
    FileKeeper
    save
    返回一个承诺,那么似乎
    ImageKeeper
    应该使用该承诺并将其链接起来。您的代码只是丢弃调用
    super.save(…)
    的结果

  • 当你发现自己在写
    新的承诺
    时,一定要停下来问问自己,所讨论的代码是否真的是链条的根。非常、非常、非常经常不是(我怀疑代码中没有)。请记住,每个
    然后
    都会返回一个承诺,而承诺的力量主要在于链条。如果你不需要的话,不要打破链条


  • 感谢您的深入调查。现在我已经结束了,将内部函数移到单独的函数中,并使用
    this.\u save.bind(this)
    应用上下文。另外,删除了额外的承诺构造函数,谢谢你们和@Benjamin花时间指出这个缺陷:)。@f1nn:不用担心。这很有趣,回答这个问题向我证明了我对
    super
    的理解是肤浅的在修复过程中学到了很多。
    root@8d1024b233c3:/src# node -v
      v4.1.1
    
    docker -v
      Docker version 1.8.2, build 0a8c2e3
    
    someAppropriateName(fileData) {
      var filePath = fileData[0],
        mime = fileData[1];
    
      super.save(filePath, mime);
    }
    
    save(filePath) {
      return new Promise((resolve, reject) => {
        this
          .resolvePath(filePath)
          .then(fileData => {                      // **
              this.someAppropriateName(fileData);  // **
          })                                       // **
          .catch(function(err) {
            reject(err)
          })
      })
    }
    
    save(filePath) {
      return new Promise((resolve, reject) => {
        this
          .resolvePath(filePath)
          .then(this.someAppropriateName.bind(this)) // **
          .catch(function(err) {
            reject(err)
          })
      })
    }