试图了解 angular 5 的范围。然后

Trying to understand scope on angular 5 .then

在这个例子中,我创建的承诺工作正常。

但是 google api 的承诺不起作用。

它说 this.youtube 未定义

index.html
<script src="https://apis.google.com/js/api.js"></script>

app.component.html

<button (click)="customClick()">custom Promise</button>
<hr>

<hello name="{{ youtube }}"></hello>
<button (click)="youtubeClick()">youtube Promise</button>

app.component.ts

import { Component } from '@angular/core';
import {  } from '@types/gapi.client.youtube';
import {  } from '@types/gapi.auth2';


export class AppComponent  {

  name = 'Angular 5';
  youtube = 'youtube';

  egPromise(){
    return new Promise<void>((resolve, reject) => {
      setTimeout(function(){
        resolve();
      }, 1000);
    });
  }

  customPromise(){
    this.egPromise().then( () => {
      this.name = 'from .then angular 5'
    });
  }

  customClick(){
    this.customPromise();
  }
/****************************************************/

youtubePromise(){
  gapi.client.init({
        apiKey: 'key',
        clientId: 'id',
        scope: "https://www.googleapis.com/auth/youtube.readonly",
        discoveryDocs: [
            "https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest"
        ]
        }).then(() => {
      this.youtube = 'from .then youtube'
    });
}

youtubeClick(){
  gapi.load('client:auth2', this.youtubePromise);
}

编辑:Solution/Explanation

在@vivek-doshi 的帮助下

我找到这个 post 搜索 "bind this"

https://www.sitepoint.com/bind-javascripts-this-keyword-react/

正如 post 解释的那样

"it’s not always clear what this is going to refer to in your code, especially when dealing with callback functions, whose callsites you have no control over."

因为我正在使用 google API 并且我无法控制该代码。

"This is because when the callback to the promise is called, the internal context of the function is changed and this references the wrong object."

加载库的函数使用回调函数,我什至没有想到第一个回调就是问题所在。

所以使用 ES2015 Fat Arrows 函数,如 post 所说。

"they always use the value of this from the enclosing scope." ... "Regardless of how many levels of nesting you use, arrow functions will always have the correct context."

因此,与其创建 bindingself 以及 thatwherever,我认为使用 =>[=23 更干净=]

让我感到困惑的另一件事是 google api 要求不带参数的回调。

所以如果你尝试使用 const that = this; gapi.load('client:auth2', this.start(that) );

会报错

但是使用 gapi.load('client:auth2', () => this.start() ); 我不是在传递参数。

这件事对很多人来说可能很简单,但既然我在学习,我会尽量让其他正在学习的人也简单。

谢谢大家

this 始终是调用该方法的对象。但是,当将方法传递给 then() 时,您并没有调用它!该方法将存储在某处并稍后从那里调用。

如果你想保留这个,你需要先保留这个:

var that = this;
// ...
.then(function() { that.method() })

在这里,您通过调用 :

失去了 this 的范围
gapi.load('client:auth2', this.youtubePromise);

将上面的代码更改为:

gapi.load('client:auth2', () => this.youtubePromise()); // ES6 Way
// OR
gapi.load('client:auth2', this.youtubePromise.bind(this)); // Traditional old way of doing

WORKING DEMO