You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5中Google API Promise回调this指向异常及解决

问题:调用Google API Promise时this.youtube未定义,自定义Promise却正常工作

问题描述

你遇到的情况是:自己编写的Promise能正常修改组件的name属性,但调用Google API的Promise时,却报错提示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';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
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();
  }

  // Google API相关逻辑
  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);
  }
}

问题根源

当你直接把this.youtubePromise作为回调传给gapi.load时,函数的this上下文会被改变——此时this不再指向你的AppComponent实例,而是指向调用这个回调的gapi内部对象,自然就找不到this.youtube这个组件属性了。

反观你的自定义Promise能正常工作,是因为在customPromise的then回调里用了箭头函数,箭头函数不会创建自己的this,它会继承外层作用域的this(也就是AppComponent实例),所以能正确访问this.name。

解决方案

这里有两种简单的修复方式:

方法1:用箭头函数包裹回调调用

修改youtubeClick方法,通过箭头函数来调用youtubePromise,这样就能保留正确的this上下文:

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

箭头函数会沿用外层(AppComponent实例)的this,所以在youtubePromise里的this依然指向组件实例,就能正常修改this.youtube了。

方法2:提前绑定this到回调函数

也可以用bind方法把this固定到youtubePromise上,再传递给gapi.load:

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

bind(this)会返回一个新函数,这个函数的this会永久绑定为AppComponent实例,调用时就不会出现上下文丢失的问题了。

内容的提问来源于stack exchange,提问作者Mateus Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:14:47