angular - 如何在第一个可观察输出用作第二个输入的时候进行 2 个可观察 / 2 个 http 调用?
问题描述
我陷入了使用toPromise()
异步方法在我的 Angular 应用程序中获取 http 数据的情况。我必须使用要传递给第二个承诺的第一个承诺数据作为再次获取数据的输入。
但是执行并没有发生在我想要的流程中。
我的TS-
IdSelection() : number[]{
var Ids : any[]=[];
this.selection.selected.forEach(element => {
Ids.push(element.Id);
});
var commIds : number[]=[];
Ids.forEach(async element => {
const res = await this.TaskService.getCmntDetails(element , 0 , '%27%27').toPromise();
if(res["commentId"] !=null){
res["commentId"].forEach(async data => {
const innerRes = await this.TaskService.getCmntDetails(0, Number(data) , '%27%27').toPromise();
innerRes["commentNewId"].forEach(ele => {
commIds.push(ele);
});
});
}
});
return commIds;
}
当我调用这个方法时,我得到了res
variable 中的值,但不久之后执行将转到 return 语句,它返回 null 。
当我在它返回 null 后进行调试和检查时,执行返回到第二个 promise 并执行了事情。
任何人都可以帮我解决如何在第一个可观察输出用作第二个输入的时候进行 2 个 observables / 2 个 http 调用吗?
TIA
解决方案
您需要创建一个最终返回所需 ID 的可观察管道:
你的例子:
from(this.selection.selected).pipe(
map(element => element.Id),
mergeMap(element => this.TaskService.getCmntDetails(element, 0, '%27%27')),
filter(res => res["commentId"] != null),
mergeMap(res => from(res["commentId"])),
mergeMap(data => this.TaskService.getCmntDetails(0, Number(data), '%27%27')),
mergeMap(innerRes => from(innerRes["commentNewId"])),
toArray()
);
让我一步一步解释这是做什么的:
这将创建一个选定元素(对象)的流。
from(this.selection.selected).pipe(
这将获取每个对象并将其映射到其Id
字段。
map(element => element.Id),
这将为每个上游元素启动异步调用。这些调用是异步启动的,并且可能以任何顺序解决。
mergeMap(element => this.TaskService.getCmntDetails(element, 0, '%27%27')),
您只需要那些具有有效数据的结果,这会过滤结果。
filter(res => res["commentId"] != null),
这会将commentId
字段“扩展”为新的 id 流。
mergeMap(res => from(res["commentId"])),
这再次启动并行调用以获取每个 id 的数据,同样,结果可能以任何顺序返回。
mergeMap(data => this.TaskService.getCmntDetails(0, Number(data), '%27%27')),
接下来我们再次“扩展”该字段commentNewId
并返回一个流。
mergeMap(innerRes => from(innerRes["commentNewId"]))
最后我们收集所有结果并将它们制成一个数组
toArray()
然后,您可以通过订阅或将其转换为 Promise 来使用上述流,有很多选择。
编辑
额外提示,如果您想要错误处理,您可以在整个流上执行,或者您可以捕获并忽略单个调用中的错误,例如:
this.TaskService.getCmntDetails(element, 0, '%27%27').pipe(catchError(_ => EMPTY))
推荐阅读
- amazon-web-services - 使用 Gitlab CI 在每次成功作业后终止现场实例
- javascript - 使用 XMLHttpRequest 但与 Fetch 一起使用时缺少正文的 POST 错误?
- javascript - 在 JavaScript 中突出显示从 '<' 开始到 '>' 的内容
- php - 谷歌图表缺少一些月份 xAxis 标签
- javascript - 如何进行javascript引导表单验证?
- gcc - 有没有人找到关闭颜色 GCC 警告/错误的方法?
- android - 为 Android 应用程序创建调试历史记录的最佳方法是什么
- python - 在一列上制作两列(python)
- blockchain - 如果比特币工作量证明在 10 分钟内没有成功,会发生什么?
- python - 有人能解释一下“defaultdict(lambda:0)”的作用吗