[英]I'm trying to use async/await to get a service, but the second service returns don't fill my variables
I have a service to get a list from server. 我有一项从服务器获取列表的服务。 But in this list I need to call another service to return the logo img, the service return ok, but my list remains empty.
但是在此列表中,我需要调用另一个服务以返回徽标img,该服务返回ok,但是我的列表仍然为空。 What i'm did wrong ?
我做错了什么?
I tried to use async/await in both services I tried to use a separate function to get the logos later, but my html don't change. 我试图在两个服务中都使用async / await,但后来尝试使用单独的功能来获取徽标,但我的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);
}
No errors, just my html don't change. 没有错误,只是我的html不变。 in my console.log(opportunities.logoDesktopUrl);
在我的console.log(opportunities.logoDesktopUrl); return undefined
返回未定义
but in the end return filled. 但最后回程充满了。
info: Angular 7 server amazon aws. 信息:Angular 7服务器亚马逊AWS。
await
is used to wait for promise
. await
用于等待promise
。
You should return promise
from getBrand
if you want to wait for it in getOpportunitiesByPage
. 您应该返回
promise
从getBrand
如果你要等它getOpportunitiesByPage
。
Change the getBrand
function as following. 如下更改
getBrand
函数。
getBrand(brandsUuid): Observable<string> {
this.brandService.getById(brandsUuid).pipe(map(res => {
console.log(res.logoDesktopUrl); return res.logoDesktopUrl;
}))
}
Change opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']);
更改
opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']);
to opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']).toPromise();
to
opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']).toPromise();
Please make sure you imported map
from rxjs/operators
. 请确保您从
rxjs/operators
导入了map
。
At first,when you await
, you should not use then
. 起初,当你
await
,你不应该用then
。
At second, async/await
runs only with Promises. 第二,
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);
});
});
}
But, because rxjs
is a used in Angular, you should use it instead of async/await
: 但是,由于
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)
);
}
Here is a working example on stackblittz 这是关于stackblittz的工作示例
There might be a simpler way to do it but it runs :-) 可能有一种更简单的方法可以执行,但它会运行:-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.