gpt4 book ai didi

angular - 使用 RxJS 从多个 API 调用构建数据

转载 作者:行者123 更新时间:2023-12-04 15:16:13 25 4
gpt4 key购买 nike

我试图更好地了解如何使用 RxJS 运算符来解决我遇到的特定问题。我实际上有两个问题,但它们非常相似。

我正在从 API 端点 /api/v3/folders/${folderId}/documents 抓取一堆文档,我已经设置了具有执行此功能的服务,并处理所有身份验证等

但是,这个文档对象数组具有描述属性。为了获得描述,我需要在上次调用的每个文档上调用 /api/v3/documents/${documentId}/ 。我的文档界面是这样的:

export interface Document {
id: number;
name: string;
description: string;
}

我在想我需要使用 mergeMap 等待并获取文档,了解如何将描述添加到我的 Document 界面并返回整个内容,但是我无法获得最终结果。

getDocuments(folderId: number) {
return this.docService.getDocuments(folderId, this.cookie).pipe(
map(document => {
document; // not entirely sure what to do here, does this 'document' carry over to mergeMap?
}),
mergeMap(document => {
this.docService.getDocument(documentId, this.cookie)
}) // possibly another map here to finalize the array?
).subscribe(res => console.log(res));
}

这可能看起来有点重复,但我发现的任何帖子都没有 100% 为我解决问题。

对于理解如何在第二次调用中正确使用数据并将其全部打包在一起的任何帮助,非常非常感谢。谢谢。

感谢@BizzyBob,这是经过编辑和解释的最终解决方案:

  getDocuments(folderId: number) {
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'Context': this.cookie$
});
return this.docService.getDocuments(folderId, this.cookie$).pipe(
mergeMap(documents => from(documents)),
mergeMap(document => this.http.get<IDocument>(
this.lcmsService.getBaseUrl() + `/api/v3/documents/${document.id}`,
{ headers: headers }
).pipe(
map(completeDoc => ({...document, description: completeDoc.description}))
)),
toArray()
).subscribe(docs => {
this.documents = docs;
console.log(this.documents);
}
)
}

出于某种原因,我无法从第二个服务订阅中 pipe(),所以我最终不得不在那里调用 http.get。错误是“无法在类型订阅上使用 pipe()”,这有点令人困惑,因为我在第一个订阅上使用了 pipe()。我将此更改应用于更新行为主题的服务功能,并且运行良好。谢谢!

最佳答案

有几种不同的方法可以从多个 api 调用中组合数据。

我们可以:

  • 使用 from 将每个项目单独发送到流中
  • 使用mergeMap订阅二级服务调用
  • 使用 toArray 在所有单独的调用完成后发出一个数组
  getDocuments() {
return this.docService.getDocuments().pipe(
mergeMap(basicDocs => from(basicDocs)),
mergeMap(basicDoc => this.docService.getDocument(basicDoc.id).pipe(
map(fullDoc => ({...basicDoc, description: fullDoc.description}))
)),
toArray()
);
}

我们还可以利用forkJoin:

  getDocuments() {
return this.docService.getDocuments().pipe(
switchMap(basicDocs => forkJoin(
basicDocs.map(doc => this.docService.getDocument(doc.id))
).pipe(
map(fullDocs => fullDocs.map((fullDoc, i) => ({...basicDocs[i], description: fullDoc.description})))
)),
);
}

这是一个有效的 StackBlitz

此外,您可以考虑将流定义为变量 documents$ 而不是方法 getDocuments()

  documents$ = this.docService.getDocuments().pipe(
mergeMap(basicDocs => from(basicDocs))
mergeMap(basicDoc => this.docService.getDocument(basicDoc.id).pipe(
map(fullDoc => ({...basicDoc, description: fullDoc.description}))
))
toArray()
);

关于angular - 使用 RxJS 从多个 API 调用构建数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64284681/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com