Асинхронный метод не возвращает значение и застрял - PullRequest
0 голосов
/ 07 апреля 2019

Я хочу получить данные пользователя вошедшего в систему пользователя из 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.

Консоль показывает:

Стартовый тест
В ожидании обещания

Поэтому мне кажется, что асинхронный вызов вообще не возвращается, потому что я ожидаю увидеть запись в лог

Test

или

Пользователь {...}

или оба.

Что не так?

Редактировать - и частичный ответ:

После еще одного исследования Google, если обнаружите на angularfirebase.com , что authState должен называться

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

Однако это смущает меня, потому что я использовал приведенный ниже код, прежде чем решил перейти к наблюдаемым вместо простых переменных. Код работал, однако я не вижу признаков какого-либо массива, который возвращается authState

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

Что происходит и почему работает мое решение?

1 Ответ

0 голосов
/ 08 апреля 2019

toPromise() создает обещание, которое будет разрешено после завершения потока.

Поэтому, если this.fireAuth.authState никогда не завершается, но выдает значения, вы можете использовать оператор first для создания потока, который завершается послепервое излучаемое значение.Таким образом, обещание разрешается.

С другой стороны, обработчик подписки вызывается для каждого значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...