【问题标题】:Angular async await not working with Http.getAngular async await 不适用于 Http.get
【发布时间】:2019-10-24 07:26:10
【问题描述】:

我有一段代码发出 http 请求以获取客户端 geoLocation,然后使用 http.get 作为参数将其发送到我的 API,我都正确完成了,但我坚持制作异步函数,我想要获取geoLocation,当它完成并且我得到它我想向我的API发出请求,我已经尝试了许多关于堆栈溢出的教程和类似问题,但我无法正确解决,有人可以建议有什么问题吗我的代码?

代码如下:

@Injectable()

export class ProductsService {

  public currency: string = '';
  public catalogMode: boolean = false;

  public compareProducts: BehaviorSubject<Product[]> = new BehaviorSubject([]);
  public observer: Subscriber<{}>;
  public static productList$: Observable<Product[]> = new Observable;
  public static test: boolean = false;

  public ipAddress: string;
  public country: string;

  // Initialize 
  constructor(private http: Http, private toastrService: ToastrService) {
    this.getIp();
    this.compareProducts.subscribe(products => products = products);
  }

  // Observable Product Array
  private products(): Observable<Product[]> {

    ProductsService.productList$.subscribe(p => {
      if (p.length != 0) {
        ProductsService.test = true;
      }
    });

    if (!ProductsService.test) {
      this.currency = this.getCurrency(this.country); //prints counrty = undefined currency = USD
      console.log('currency 1 = ' + this.currency); // prints defualt currency USD?
      ProductsService.productList$ = this.http.get('http://localhost:8080/products/getAllProducts?currency='+this.currency).map((res: any) => {
        ProductsService.test = true;
        this.currency = this.getCurrency(this.country);  // calling the function here works as I want
        console.log('currency 2 = ' + this.currency); // prints the expected values
        return res.json();
      });

    }
    return ProductsService.productList$;
  }

  // Get Products
  public getProducts(): Observable<Product[]> {
    return this.products();
  }

  async getIp() {
    await this.http.get(('http://ip-api.com/json/' + '?fields=countryCode')).toPromise().then(r => {
      this.country = r.json().countryCode;
    });
  }

  private getCurrency(country: string): string {
    if (country === 'JO') {
      this.currency = 'JOD';
    } else if (country === 'AE') {
      this.currency = 'AED';
    } else if (country === 'SA') {
      this.currency = 'SAR';
    } else if (country === 'GB') {
      this.currency = 'GBP';
    } else if (country === 'DE') {
      this.currency = 'EUR';
    } else if (country === 'KW') {
      this.currency = 'KWD';
    } else if (country === 'EG') {
      this.currency = 'EGP';
    } else {
      this.currency = 'USD';
    }
    console.log("counrty = " + country + " currency = " + this.currency); //prints counrty = GB currency = GBP
    return this.currency;
  }

}

运行代码时控制台会输出:

counrty = undefined currency = USD
currency 1 = USD
counrty = GB currency = GBP
currency 2 = GBP
counrty = GB currency = GBP
currency 2 = GBP

【问题讨论】:

  • 你在哪里调用getProducts()函数?
  • @pindev 它被其他组件调用
  • 是在getIp完成之前调用的吗?
  • 我不确定你能帮我追踪代码吗?它在其他组件中的 ngOnInit() 中被调用,但请注意我在构造函数中调用了 getIp(),并尝试将其放在 products() 方法的第一行但同样的问题
  • 您可以在getProductsgetIp的开头添加console.log,以确保首先调用哪个。

标签: angular async-await httprequest


【解决方案1】:

您可以在getProducts() 中调用await this.getIp() 等待完成。

import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { map, switchMap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ProductsServiceService {

  private products: Product[];

  // Initialize
  constructor(private http: HttpClient) {
  }

  // Get Products
  public getProducts(): Observable<Product[]> {
    if (this.products) {
      return of(this.products);
    } else {
      return this.getIp().pipe(
        switchMap(country => {
          const currency = this.getCurrency(country);
          console.log('currency 1 = ' + currency);
          return this.http.get('http://localhost:8080/products/getAllProducts?currency=' + currency).pipe(
            map((res: any) => {
              console.log('currency 2 = ' + currency); // prints the expected values
              return res.json();
            })
          );
        })
      );
    }
  }

  getIp() {
    return this.http.get<any>(('http://ip-api.com/json/' + '?fields=countryCode')).pipe(
      map(r => r.json().countryCode)
    );
  }

  private getCurrency(country: string): string {
    let currency;

    if (country === 'JO') {
      currency = 'JOD';
    } else if (country === 'AE') {
      currency = 'AED';
    } else if (country === 'SA') {
      currency = 'SAR';
    } else if (country === 'GB') {
      currency = 'GBP';
    } else if (country === 'DE') {
      currency = 'EUR';
    } else if (country === 'KW') {
      currency = 'KWD';
    } else if (country === 'EG') {
      currency = 'EGP';
    } else {
      currency = 'USD';
    }
    console.log('counrty = ' + country + ' currency = ' + currency);
    return currency;
  }

}

【讨论】:

  • 这帮助我在产品之前获得了ip和货币,但我又多次调用了api!
  • 哦,我错过了一件事。在return res.json();之前添加this.products = res.json();
  • 我这样做了,但是没有用,在第 3 次调用后就可以了
【解决方案2】:

Async/Await 并不是这样工作的。 您必须将承诺分配给一个变量,如下所示:

async getIp() {
  const resposne = await this.http.get('http://ip-api.com/json/' + '?fields=countryCode').toPromise();
 ..... do stuff with your response ....
  }

【讨论】:

    猜你喜欢
    • 2019-05-08
    • 2018-03-24
    • 1970-01-01
    • 2018-08-23
    • 2018-07-10
    • 2019-02-27
    • 2021-06-18
    • 2019-05-30
    • 2021-05-10
    相关资源
    最近更新 更多