如何在promise的回调中设置`this`的上下文

时间:2017-01-31 19:56:41

标签: javascript promise this

当我在Promise上调用resolve()时,then()中的函数绑定到window的范围。

有什么办法可以像使用Function.apply方法一样设置它的上下文?

function Point(){
  var that = this;
  
  var _x = 0;
  
  this.setX = function(x){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            _x = x;
            resolve.apply(that); //<== set this
        }, 1000);
    });
  }

  this.getX = function(){
    return _x;
  }
}

var p = new Point();
p.setX(10).then(function(){
  console.log(this.getX()); //this === `window`
});

编辑:

通过简单地反复返回相同的对象,使用同步代码进行方法链接,可以进行方法链接。

//this pattern
obj.method1();
obj.method2();
...


//becomes this pattern
obj.method1(10).method2(11) ...

实施链接

method1 = function(x){
    return this;
}

说到assync,你仍然可以用回调做同样的事情

obj.method1(10, function(){ this.method2(11, function(){ ...

使用回调实现

method1 = function(x, cb){
    cb.apply(this);
}

我不明白为什么有人将“接收器”功能绑定到窗口,这对我来说没有意义,因为承诺应该类似于同步调用。

1 个答案:

答案 0 :(得分:1)

选项1:

您可以将实例传递给resolve函数。然后通过回调引用它作为第一个参数。

function Point() {
  var that = this;

  var _x = 0;

  this.setX = function(x) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        _x = x;
        resolve(that); //<== set this
      }, 1000);
    });
  }

  this.getX = function() {
    return _x;
  }
}

var p = new Point();
p.setX(10).then(function(scope) {
  console.log(scope.getX());
});

选项2:

您可以绑定回调的范围:

var p = new Point();
p.setX(10).then(function () {
    console.log(this.getX()); //this === `window`
}.bind(p)); // bind the scope here

function Point() {
  var that = this;

  var _x = 0;

  this.setX = function(x) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        _x = x;
        resolve.apply(that); //<== set this
      }, 1000);
    });
  };

  this.getX = function() {
    return _x;
  }
}

var p = new Point();
p.setX(10).then(function() {
  console.log(this.getX()); //this === instance of Point
}.bind(p));