首页 > 解决方案 > 异步方法不返回值并卡住

问题描述

我想从 Google Firebase 获取登录用户的用户数据。为此,我写了两种方法;一个获得authState另一个获得UserInfo包含更详细的信息。

这些是在名为的服务中实现的两种方法UserService

constructor(private fireStore: AngularFirestore, private fireAuth: AngularFireAuth) {
}

public async getAuthorizedUser(): Promise<UserInfo> {
  console.log('Awaiting Promise');
  const user: firebase.User = await this.fireAuth.authState.toPromise();
  console.log('User', user);
  return this.getUserInfo(user.uid);
}

private async getUserInfo(uid: string): Promise<UserInfo> {
  return this.fireStore.collection('users', ref => ref.where('uid', '==', uid))
             .get()
             .pipe(
               map((item: firebase.firestore.QuerySnapshot) => new UserInfo(item.docs[0].data(), item.docs[0].id))).toPromise();
}

getAuthorizedUser从组件中实现的按钮事件处理程序调用该方法。按钮的 html 元素如下所示:

<button mat-button (click)="test()">test</button>

test()方法实现为:

async test() {
  console.log('Starting Test');
  const testVariable = await this.userService.getAuthorizedUser();
  console.log('Test', testVariable);
}

此外,userService是注入的依赖项UserService

控制台显示:

开始测试
等待承诺

因此,在我看来,异步调用根本没有返回,因为我希望看到日志记录

测试

或者

用户 {...}

或两者。

怎么了?

编辑 - 和部分答案:

如果在angularfirebase.com上找到更多谷歌研究,则应该将 authState 称为

const user: firebase.User = await this.fireAuth.authState.pipe(first()).toPromise();

然而,这让我感到困惑,因为在我决定更改为 observables 而不是普通变量之前,我使用了下面的代码。代码有效,但是我看不到任何由返回的数组的迹象authState

this.fireAuth.authState.subscribe((user: firebase.User) => {
  if (user) {
    this.getUserData(user.uid);
  }
});

发生了什么,为什么我的解决方案有效?

标签: angulartypescriptasync-awaitfirebase-authenticationgoogle-cloud-firestore

解决方案


toPromise()创建一个将在流完成时解决的承诺。

因此,如果this.fireAuth.authState从未完成,但发出值,您可以使用first运算符创建一个在第一个发出值之后完成的流。因此,诺言解决了。

另一方面,订阅处理程序会为每个值调用。


推荐阅读