我正在尝试使用async / await来获取服务,但是第二个服务返回的值却没有填满我的变量

时间:2019-06-18 02:28:20

标签: javascript angular

我有一项从服务器获取列表的服务。但是在此列表中,我需要调用另一个服务以返回徽标img,该服务返回ok,但是我的列表仍然为空。我做错了什么?

我试图在两个服务中都使用异步/等待 我尝试使用单独的功能稍后再获取徽标,但我的html不变。

 async getOpportunitiesByPage(_searchQueryAdvanced: any = 'active:true') {
    this.listaOportunidades = await this._opportunities
      .listaOportunidades(this.pageSize, this.currentPage, _searchQueryAdvanced)
      .toPromise()
      .then(result => {
        this.totalSize = result['totalElements'];
        return result['content'].map(async (opportunities: any) => {
          opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']);
          console.log(opportunities.logoDesktopUrl);
          return { opportunities };
        });
      });

    this.getTasks(this.totalSize);
  }

没有错误,只是我的HTML不变。 在我的 console.log(opportunities.logoDesktopUrl); 返回未定义

但最后的回报已填满。

信息: 角度7 服务器亚马逊aws。

2 个答案:

答案 0 :(得分:0)

await用于等待promise

如果要在promise中等待,请从getBrand返回getOpportunitiesByPage

如下更改getBrand函数。

getBrand(brandsUuid): Observable<string> {
  this.brandService.getById(brandsUuid).pipe(map(res => { 
    console.log(res.logoDesktopUrl); return res.logoDesktopUrl;
  }))
}

opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']);更改为opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']).toPromise();

请确保您从map导入了rxjs/operators

答案 1 :(得分:0)

首先,当您await时,请勿使用then

第二,async/await仅与Promises一起运行。

async getOpportunitiesByPage(_searchQueryAdvanced: any = 'active:true') {
  const result = await this._opportunities
    .listaOportunidades(this.pageSize, this.currentPage, _searchQueryAdvanced)
    .toPromise();
  this.totalSize = result['totalElements'];
  this.listaOportunidades = result['content'].map(async (opportunities: any) => {
    opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']);
    console.log(opportunities.logoDesktopUrl);
    return opportunities;
  });

  this.getTasks(this.totalSize);
}

getBrand(brandsUuid) { 
  return new Promise((resolve, reject) => {
    this.brandService.getById(brandsUuid).subscribe(res => { 
      console.log(res.logoDesktopUrl);
      return resolve(res.logoDesktopUrl);
    }, err => {
      return reject(err);
    });
  });
}

但是,由于rxjs是Angular中的常用词,因此您应该使用它而不是async/await

getOpportunitiesByPage: void(_searchQueryAdanced: any = 'active:true') {
  this._opportunities.listaOportunidades(this.pageSize, this.currentPage, _searchQueryAdvanced).pipe(
    tap(result => {
      // we do that here because the original result will be "lost" after the next 'flatMap' operation
      this.totalSize = result['totalElements'];
    }),
    // first, we create an array of observables then flatten it with flatMap
    flatMap(result => result['content'].map(opportunities => this.getBrand(opportunities['brandsUuid']).pipe(
        // merge logoDesktopUrl into opportunities object
        map(logoDesktopUrl => ({...opportunities, ...{logoDesktopUrl}}))
      )
    ),
    // then we make each observable of flattened array complete
    mergeAll(),
    // then we wait for each observable to complete and push each result in an array
    toArray()
  ).subscribe(
    opportunitiesWithLogoUrl => { 
      this.listaOportunidades = opportunitiesWithLogoUrl;
      this.getTasks(this.totalSize);
    }, err => console.log(err)
  );
}

getBrand(brandsUuid): Observable<string> {
  return this.brandService.getById(brandsUuid).pipe(
    map(res => res.logoDesktopUrl)
  );
}

这是stackblittz

上的有效示例

可能有一种更简单的方法,但它可以运行:-)