【问题标题】:Trying to understand scope on angular 5 .then试图了解角度 5 .then 的范围
【发布时间】:2018-08-25 04:07:06
【问题描述】:

在这个例子中,我创建的 Promise 可以正常工作。

但是来自 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);
}

编辑:解决方案/解释

在@vivek-doshi 的帮助下

我发现这篇文章搜索“绑定这个”

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

正如帖子解释的那样

“在你的代码中 this 指的是什么并不总是很清楚,尤其是在处理回调函数时,你无法控制其调用点。”

由于我使用的是 google API,我无法控制该代码。

“这是因为在调用 promise 的回调时,函数的内部上下文发生了变化,并且 this 引用了错误的对象。”

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

如帖子所述,使用 ES2015 Fat Arrows 函数。

“他们总是使用封闭范围内的 this 的值。” ... “无论您使用多少层嵌套,箭头函数都将始终具有正确的上下文。”

因此,与其创建bindingselfthatwherever,我认为使用=&gt; 更干净

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

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

它会抱怨。

但是使用 gapi.load('client:auth2', () =&gt; this.start() ); 我没有传递参数。

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

谢谢大家。

【问题讨论】:

  • 请将代码的相关部分贴在这里
  • 抱歉,发错链接了,现在可以了
  • 不过,您应该在此处发布所有相关部分以供将来的查看者使用,因为链接可能会失效。此外,非常欢迎您发布链接供人们使用它,但回答您问题所需的一切都应该在 * 上
  • 关于this的有用阅读:*.com/questions/20279484/…
  • @daniel-hilgarth 可以在这里发布 Angular 5 项目吗?代码 sn-p 只有 1.2.23

标签: javascript angular promise google-api-js-client google-client-login


【解决方案1】:

在这里,您通过调用将失去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

【讨论】:

  • 好的,所以这行得通gapi.load('client:auth2', () =&gt; this.youtubePromise());,但我不完全明白为什么。你能指出一些关于它的东西吗,因为我什至不知道要搜索什么,我在发布之前做了很多研究并且没有遇到任何类似的代码。
  • @MateusSilva,这种问题大部分发生在 react 端,在事件绑定的时候,如果你想得到更多关于这个的东西,你可以通过 react 搜索,更多细节请谷歌@987654326 @
  • @MateusSilva ,请您也接受答案吗:)
  • 我会,但我会尝试编辑帖子并提供有关问题和答案的更多有用信息。谢谢@vivek-doshi
  • @MateusSilva,谢谢,BTW 编码愉快 :)
【解决方案2】:

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

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

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

【讨论】:

    最近更新 更多