背景
我正在构建一个 Angular 应用程序,其中列出了在给定地址注册的公司。
给出一些上下文......
假设我有 x3 个公司:公司 A、公司 B 和公司 C。
B 公司的注册地址与 A 公司相同。C 公司不是。
当我导航到应用程序并筛选公司 A 时,我希望在列表中只看到公司 B。
问题
我的问题不是我不能让它工作,它太慢了!我需要以某种方式利用多线程/并发。
为了确定在给定地址注册了哪些公司,我必须进行多次 HTTP 调用。
在解释我进行 HTTP 调用的顺序之前。让我向您展示 API 的样子:
GET /api/companies/CompanyA/address
{
id: 1,
addressLine1: '123 Some street',
...
}
GET /api/companies/CompanyA/links
[
{id: 2, name: 'Company B'},
{id: 3, name: 'Company C'},
]
对了,顺序是这样的:
- 获取公司 A 的地址并存储 ID
- 获取公司 A 的链接
- 遍历每个链接 3a.获取链接地址 3b.检查地址 ID 是否与公司 A 的地址 ID 匹配。如果是,请存储链接。
当前实现
const companyAId: number = 1;
const companyAAddress: Object = await this.httpService.getAddress(companyAId).toPromise();
const companyALinks: Object[] = await this.httpService.getLinks(companyAId).toPromise();
const companiesToShow: Object[] = [];
for (let link of links) {
const linkAddress: Object = await this.httpService.getAddress(link ['id']).toPromise();
if (linkAddress['id'] === companyAAddress['id']) companiesToShow.push(link );
}
一定有更优雅/更高效的解决方案!
任何帮助将不胜感激:)
谢谢,
本
最佳答案
您是正确的,每个 API 调用都必须先等待另一个调用完成。
您本身无法访问多线程,但您可以在编写时使用 Promise.all
使其并发。具体来说,您可以同时检索地址和链接,然后同时检索所有其他地址。我已经缩短了一些方法调用名称以使其更易于编写:
const [companyAAddress, companyALinks] = await Promise.all(
getAddress(id).toPromise(),
getLinks(id).toPromise(),
);
const companiesToShow = await Promise.all(links.map(link => getAddress(link.id).pipe(
map(linkAddress => [link, linkAddress]),
filter(([, { id }]) => id === companyAAddress.id),
).toPromise())
除了使用 promises 之外,您还可以严格使用 Observables 来做到这一点,这将使它可以取消。
forkJoin(getAddress(id), getLinks(id)).pipe(
mergeMap(([companyAAddress, companyALinks]) => companyALinks.map(link => getAddress(link.id).pipe(
map(linkAddress => [link, linkAddress]),
filter(([, { id }]) => id === companyAAddress.id),
))
)
但是,我会说从单个请求中获取链接公司的能力应该由服务器实现。
关于angular - 如何使用 RxJS 并行化多个 HTTP 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52391098/