javascript - 异步等待与承诺与映射?
问题描述
如何在承诺、异步等待和映射运算符(如 concatMap)之间做出决定?
这是我的具体情况,但我也很好奇您一般如何决定:
我正在对我的后端进行 http 调用,然后我再进行一次 http 调用。在处理第二次调用的 json 数据时,我需要使用第一次调用返回的值。在这种情况下,使用 async await、promise 还是 concatMap 会更好吗?同样,一般来说,决定使用哪个指南是什么?
这是我目前拥有的,使用 concatMap。(我从我的 getTask http 调用动态生成子组件,每个子组件都需要访问 annotationFormats)。
this.dashboardService.getAnnotationFormats()
.pipe(
concatMap(annotationFormats=> this.dashboardService.getTasks())
)
.subscribe(
(tasks)=>{
for(let task of tasks){
const componentFactory=this.CFR.resolveComponentFactory(DashboardItemComponent);
const componentRef=this.vc.createComponent(componentFactory);
componentRef.instance.task=task;
componentRef.instance.annotationFormats=annotationFormats;
componentRef.instance.compInteraction=this;
this.taskRef.push(componentRef);
}
}
);
解决方案
Async/await 和 promises 基本相同,只是语法不同。在某些作业完成后将运行一次的异步代码。
通常,在使用 Angular 时,我永远不会使用这些。Angular 提供了开箱即用的 RxJS,这不仅仅是承诺。您可以在作业完成后使用 RxJS 运行一次异步代码,但它也为您提供了创建数据流并以多种不同方式操作它们的可能性。完全理解 RxJS 和响应式编程确实需要一点时间,但是一旦你明白了你可以用它做多少。
在您的情况下,我喜欢使用 operator forkJoin
,因为这两个请求似乎彼此独立。您可以给它一个您想要获取的资源列表,并在它们全部完成后执行订阅中的异步代码,这使其非常适合 http 请求:
forkJoin({
annotationFormats: this.dashboardService.getAnnotationFormats(),
tasks: this.dashboardService.getTasks(),
})
.subscribe(
({tasks, annotationFormats})=>{
for(let task of tasks){
const componentFactory=this.CFR.resolveComponentFactory(DashboardItemComponent);
const componentRef=this.vc.createComponent(componentFactory);
componentRef.instance.task=task;
componentRef.instance.annotationFormats=annotationFormats;
componentRef.instance.compInteraction=this;
this.taskRef.push(componentRef);
}
}
);
花点时间学习 RxJS,我保证它会得到回报。每当你在使用 RxJS 并且感觉太复杂或错误时,那可能是因为它可能是。前往 RxJS 文档并寻找可能有用的东西,如果你没有找到任何东西,快速谷歌搜索可能会为你找到解决方案。重点是,不要只是盲目地使用它,要始终尝试了解它是如何工作的。
我希望这很有用。:)
编辑:
对于 RxJS < 6.5,语法有点不同:
forkJoin(
this.dashboardService.getTasks(),
this.dashboardService.getAnnotationFormats()
)
.subscribe(
([tasks, annotationFormats])=>{
for(let task of tasks){
const componentFactory=this.CFR.resolveComponentFactory(DashboardItemComponent);
const componentRef=this.vc.createComponent(componentFactory);
componentRef.instance.task=task;
componentRef.instance.annotationFormats=annotationFormats;
componentRef.instance.compInteraction=this;
this.taskRef.push(componentRef);
}
}
);
请注意,我们将资源作为参数而不是对象传递,并且订阅中的结果也将以数组形式而不是对象形式。
推荐阅读
- java - BackgroundPanel 我的背景图片覆盖了我的所有组件
- java - 如何同时进行 API 调用
- python-3.x - 在 input() 之后删除行空间
- c# - 如何用鼠标在现有的pdf中绘制矩形
- r - 如何从 powershell 运行 R 脚本并将所有打印输出写入文件?
- android - 单例对象的变量随机设置为 NULL
- javascript - 打印前2个不重复的数字javascript
- reactjs - React Project 中需要 babel 吗?
- python - 如何从属性中解析文本
- java - java.lang.SecurityException:权限拒绝:实现内容提供者时打开提供者