如何在.then()中访问调用ES6 Promise的类实例?

时间:2018-06-22 02:14:26

标签: javascript ecmascript-6 es6-promise

我正试图在承诺中解决this,但不知道为什么它不起作用。箭头函数通常为我完成此操作,但是比平常要复杂一些。

例如,下面的代码段出现以下错误:

  

TypeError:无法读取未定义的属性'processResponse'

this在哪里迷路?

如果下面的代码段不起作用,请尝试this codepen

class Page {
  init() {
    this.datatable = new Datatable();
    this.datatable.setBehavior(this.behaviorFlavor)
  }

  behaviorFlavor() {
    console.log('Doing action...');
    Ajax.get()
      // 'this' is undefined
      .then((data) => { this.processResponse(data) });
  }

  processResponse(data) {
    console.log('Processing response...');
  }
}

class Datatable {
  setBehavior(callback) {
    // Add event listener to rows, etc.
    $('button').click(() => {
      callback();
    });
  }
}

class Ajax {
  static get() {
    return new Promise(function(resolve, reject) {
      console.log("Sending request...");
      resolve();
    })
  }
}

(new Page).init();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>
  <button>Click Here!</button>
  <p>Then check your browser's console to see the error.</p>
</div>

2 个答案:

答案 0 :(得分:3)

通过将this函数引用作为回调传递,behaviorFlavor上下文丢失了。您基本上是从类中提取该方法并尝试隔离执行。

尝试这些替代方法之一...

  1. 使用箭头功能锁定 this上下文

    setBehavior(() => { this.behaviorFlavor() })
    
  2. 直接bind behaviorFlavor函数

    setBehavior(this.behaviorFlavor.bind(this))
    

答案 1 :(得分:2)

您当前的代码中没有调用上下文,因为函数调用的发起者只是callback();。在将bind设置为this.behaviorFlavor之前,请尝试将其this设置为class Page { init() { this.datatable = new Datatable(); this.datatable.setBehavior(this.behaviorFlavor.bind(this)) } behaviorFlavor() { console.log('Doing action...'); Ajax.get() // 'this' is undefined .then((data) => { this.processResponse(data) }); } processResponse(data) { console.log('Processing response...'); } } class Datatable { setBehavior(callback) { // Add event listener to rows, etc. $('button').click(() => { callback(); }); } } class Ajax { static get() { return new Promise(function(resolve, reject) { console.log("Sending request..."); resolve(); }) } } (new Page).init();

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>
  <button>Click Here!</button>
  <p>Then check your browser's console to see the error.</p>
</div>
<img>