为什么'这个'使用promises时,在类方法中是否未定义?

时间:2016-01-21 17:46:48

标签: javascript node.js promise this q

我有一个javascript类,每个方法都返回一个Q承诺。我想知道thismethod2method3未定义的原因。有没有更正确的方法来编写这段代码?

function MyClass(opts){
  this.options = opts;

  return this.method1()
    .then(this.method2)
    .then(this.method3);
}

MyClass.prototype.method1 = function(){
  // ...q stuff...

  console.log(this.options); // logs "opts" object

  return deferred.promise;
};

MyClass.prototype.method2 = function(method1resolve){
  // ...q stuff...

  console.log(this); // logs undefined

  return deferred.promise;
};

MyClass.prototype.method3 = function(method2resolve){
  // ...q stuff...

  console.log(this); // logs undefined

  return deferred.promise;
};

我可以使用bind

解决此问题
function MyClass(opts){
  this.options = opts;

  return this.method1()
    .then(this.method2.bind(this))
    .then(this.method3.bind(this));
}

但不完全确定为什么bind是必要的;是.then()关闭了this

4 个答案:

答案 0 :(得分:119)

// keyboard down window check. window.addEventListener("keydown", function(event) { onKeyDownHandler(event); }, false); function onKeyDownHandler(e) { e.preventDefault(); var focus_id = e.target.id; switch (e.keyCode) { case 46: // delete //delete item alert("why i cant get this work on mac?"); break; } } 始终是调用方法的对象。但是,将方法传递给this时,您没有调用它!该方法将存储在某处并在稍后从那里调用。如果你想保留then(),你必须这样做:

this

或者如果你必须以ES6之前的方式进行,你需要在{I}之前保留.then(() => this.method2())

this

答案 1 :(得分:18)

默认情况下,在全局对象(window)的上下文中调用Promise处理程序。在严格模式(use strict;)下,上下文为undefined。这就是method2method3发生的事情。

;(function(){
  'use strict'
  Promise.resolve('foo').then(function(){console.log(this)}); // undefined
}());

;(function(){
  Promise.resolve('foo').then(function(){console.log(this)}); // window
}());

对于method1,您将method1称为this.method1()。这种调用方式在this对象的上下文中调用它,这是您的实例。这就是method1内的上下文是实例的原因。

答案 2 :(得分:2)

基本上,您传递了一个没有上下文引用的函数引用。 #resultsRepeaterGrid tr[class="row"],tr[class="altrow"] 上下文的确定方式有以下几种:

  1. 隐式。调用全局函数或没有绑定的函数假定全局上下文。*
  2. 直接参考。如果您致电this,则myObj.f()将成为myObj背景。**
  3. 手动装订。这是您的一类功能,例如this.bind。这些是您明确说明.apply上下文的内容。这些始终优先于前两个。
  4. 在您的示例中,您传递了一个函数引用,因此在它的调用中,它隐含为全局函数或没有上下文的函数。使用this可以通过创建一个显式设置.bind的新函数来解决此问题。

    *仅在非严格模式下才是这样。在严格模式下,this设置为this

    **假设您使用的功能尚未手动绑定。

答案 3 :(得分:0)

单向函数获取其上下文(this)来自调用它们的对象(这就是为什么method1具有正确的上下文 - 它在{{1}上调用的原因})。您正在将函数本身的引用传递给this。您可以想象then的实现看起来像这样:

then

在该示例中,function then( callback ) { // assume 'value' is the recently-fulfilled promise value callback(value); } 是对您的函数的引用。它没有任何背景。正如您已经注意到的那样,在将函数传递给上下文之前,您可以通过将函数绑定到上下文来解决这个问题。