Angular 9:使用命名函数作为 then()、listen() 和 subscribe() 的参数的范围问题

Angular 9: Scoping Issues Using Named Functions as Arguments for then(), listen(), and subscribe()

无法理解为什么我遇到范围界定问题。

使用 then() 中定义的函数时,一切正常:

import GoogleAuth = gapi.auth2.GoogleAuth;
import GoogleUser = gapi.auth2.GoogleUser;

@Injectable()
export class MyService {
  constructor() { }

  private googleAuth: GoogleAuth = undefined;
  private clientConfig = { ... };

  public init(): void {
    gapi.load('auth2', () => {
      gapi.auth2.init(this.clientConfig)
        .then((response: GoogleAuth) => {
          this.googleAuth = response;
      });
    });
  }
}

但是,当我尝试使用命名函数作为 then() 的参数时,出现错误(代码行旁边):

import GoogleAuth = gapi.auth2.GoogleAuth;
import GoogleUser = gapi.auth2.GoogleUser;

@Injectable()
export class MyService {
  constructor() { }

  private googleAuth: GoogleAuth = undefined;
  private clientConfig = { ... };

  private onInit(response: GoogleAuth): void {
    console.log(this); // undefined
    this.googleAuth = response; // Cannot read property 'googleAuth' of undefined
  }

  public init(): void {
    gapi.load('auth2', () => {
      gapi.auth2.init(this.clientConfig)
        .then(this.onInit);
    });
  }
}

起初我以为是因为我将 undefined 指定为“googleAuth”的值,但即使我 运行“console.log(this );"在“onInit”内部,undefined 是出现在控制台中的内容。如果我手动调用该方法并传递预期的参数,则可以轻松看到“this”和“this.googleAuth”。我在使用 listen() 和 subscribe() 时遇到完全相同的问题。

我该如何解决这个问题?

您将函数 this.onInit 传递给 then 的方式会丢失上下文。正确的做法是

    public init(): void {
      gapi.load('auth2', () => {
        gapi.auth2.init(this.clientConfig)
          .then((resp) => this.onInit(resp));
        });
    }

注意胖箭头功能的使用