首页 > 解决方案 > 异步等待与承诺与映射?

问题描述

如何在承诺、异步等待和映射运算符(如 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);
          }
        }
    );

标签: javascriptangulartypescript

解决方案


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);
      }
    }
);

请注意,我们将资源作为参数而不是对象传递,并且订阅中的结果也将以数组形式而不是对象形式。


推荐阅读