在Promise中调用super()方法:'super'关键字在这里出乎意料?

时间:2015-10-04 10:55:58

标签: inheritance scope ecmascript-6 super es6-promise

我正在尝试从子实例调用超级方法// 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 ... } }

/src/filekeeper/imagekeeper.js:110
          super.save(filePath, mime);
          ^^^^^

SyntaxError: 'super' keyword unexpected here

我收到错误:

super.save(filePath, mime);

如果我在save()方法的开头移动save(filePath) { return new Promise((resolve, reject) => { this .then((fileData) => { // <-- bind context to upper scope super.save(filePath, mime); ,那就可以了。

我已尝试将绑定上下文绑定到较高范围:

Unhandled rejection SyntaxError: 'super' keyword unexpected here
    at processImmediate [as _immediateCallback] (timers.js:374:17)
From previous event:
    at /src/filekeeper/imagekeeper.js:106:10

但我得到了:

root@8d1024b233c3:/src# node -v
  v4.1.1

docker -v
  Docker version 1.8.2, build 0a8c2e3

阅读this,但没有运气。

有什么想法吗?谢谢。

的env

Class.forName("org.postgresql.Driver");

1 个答案:

答案 0 :(得分:9)

看起来您在V8处理super时发现了一个错误;我已经报告了错误here,他们将其分类为Type-BugPriority-Medium。这是在仔细研究之后,导致我发布this question,其中this answer证实我怀疑这是一个V8错误。

如果您使用箭头功能(不是function功能),那么我已经尝试将绑定上下文绑定到较高范围&#34;评论(主代码块使用的是function函数,但该函数无法正常工作, 应该正常工作。

在等待修复时,如果将该逻辑放在方法中,它就可以工作:

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)
      })
  })
}

或:

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

这是有效的,因为错误是相当模糊的:只有在方法内的另一个箭头函数内部有箭头函数时,它才会出现,而最里面的箭头函数使用由该方法定义的变量或参数。外部箭头功能(使用方法本身的东西很好)。

其他一些说明:

  1. 如果FileKeeper&#39; s save返回一个承诺,似乎ImageKeeper应该使用它并将其链接起来。您的代码只会丢弃调用super.save(...)的结果。

  2. 当您发现自己正在撰写new Promise时,请始终停下来问问自己,相关代码是否确实是链的根。非常,非常,经常不是(我怀疑它不在你的代码中)。请记住,每个then都会返回一个承诺,而承诺的力量主要在于链条。如果你不必,不要打破链条。