Как использовать js async / await в нескольких асинхронных запросах - PullRequest
0 голосов
/ 05 ноября 2019

Я использую Angular 7, теперь есть метод (Angular guard CanActivate), который содержит несколько вложенных методов вызова http, мне нужно возвращать данные после завершения всех вложенных вызовов http.

Как показано в коде ниже, только после того, как getCurrentUser() закончено, верните результат в canActivate(), тогда как теперь всегда возвращается false, потому что getCurrentUser() еще не закончено.

export class AuthGuard implements  CanActivate{


  constructor(private commonService: CommonService) {
  }

  async canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    console.log('======');
    await this.getCurrentUser();
    return this.hasAccess;
  }

  hasAccess: boolean = false;

  async getCurrentUser(){
    await this.commonService.getToken().subscribe(token => {
      this.commonService.getCurrentUser(param, token).subscribe(o => {
        if(o.success){

          this.hasAccess = true;

        }else {
            window.location.href = '/forbidden.html';
          }
      }, error => {
        console.log(error);
      });
    });
    console.log("async");
  }
}

Вы можете видеть, что есть два асинхронных метода: A, B должны быть в ожидании, и A, B не параллельны, я проверил документы об Promise и async / await, не нашел решения.

Поскольку ожидание всегда должно следовать за асинхронным, как я могу позволить canActivate() вернуть результат после завершения всего асинхронного http-вызова?

+++ Обновление

this.commonService.getToken() иthis.commonService.getCurrentUser(param, token) http http (HttpClient), я пробовал много решений, но безрезультатно.

Ответы [ 3 ]

0 голосов
/ 05 ноября 2019

Вы можете использовать комбинацию async await и Promise.all. Таким образом, вы можете дождаться всех ваших асинхронных сетевых запросов и, когда все запросы будут выполнены, выполнить какое-то действие.

A Promise.all() принимает массив обещаний и объединяет их в одно обещание. И мы уже знаем хороший синтаксис для работы с одним обещанием. Мы можем его дождаться.

Для вашего понимания взгляните на этот пример кода:

let films = await Promise.all(
  characterResponseJson.films.map(async filmUrl => {
    let filmResponse = await fetch(filmUrl)
    return filmResponse.json()
  })
)
console.log(films)

Я привел этот пример из этой статьи, который может помочь вам найти решение

Как использовать async / await с картой и Promise.all

Обновление: для вашего случая использования вы можете использовать так:

async getCurrentUser(){
  await this.commonService.getToken().subscribe(async token => {
    await this.commonService.getCurrentUser(param, token).subscribe(o => {
      if(o.success){

        this.hasAccess = true;

      }else {
          window.location.href = '/forbidden.html';
        }
    }, error => {
      console.log(error);
    });
  });
  console.log("async");
}
0 голосов
/ 11 ноября 2019

Обратитесь к ответам выше и помощи других людей, я обновляю свой код, и теперь он работает. Мое обновление использует new Promise() в getToken () , getUser () вместо await оно, Promise имеет статус ( в ожидании , решено , отклонено ), после изменения статуса оно все равно не изменится, таким образом, как только статус Promise изменится на восстановлен , он выиграл 'не будет изменено, и Promise вернет его значение, в противном случае произойдет ошибка, если изменить на отклонить .

Прикрепите мой обновленный код, как показано ниже:

canActivate:

async canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    console.log('======');
    let token = await this.getToken();
    // let hasAccess = await this.getUser(token);
    return await this.getUser(token);
  }

getToken () и getUser () :

// return a Promise object and resolve(token)
getToken(){
    return new Promise((resolve, reject)=>{
      this.commonService.getToken().subscribe(token=>{
        resolve(token)
      })
    })
  }

  getUser(token: any) {
    return new Promise<boolean>((resolve, reject) => {
      this.commonService.getCurrentUser(param, token).subscribe(o => {
        if(o.success){

          hasAccess = true;
        }else {
          window.location.href = '/forbidden.html';
        }
        resolve(hasAccess);
      }, error => {
        console.log(error);
        resolve(hasAccess);
      });
    })
  }

Я не очень знаком с async / await и Promise , поэтому приветствуем исправление ошибки.

0 голосов
/ 05 ноября 2019

Метод Promise.all () - это то, что вы ищете.

...