异步等待vs承诺vs映射?

时间:2019-11-12 21:28:55

标签: javascript angular typescript

如何在promise,async await和映射操作符(例如concatMap)之间做出选择?

这是我的具体情况,但我也对您的一般决定感到好奇:

我正在对后端进行http调用,然后再进行另一个http调用。在处理第二个调用的json数据时,我需要使用第一个调用返回的值。在这种情况下,使用async await,promise或concatMap更好吗?同样,总体上,决定使用哪种准则是什么?

这是我当前使用concatMap所拥有的。 (我正在通过getTask http调用动态生成子组件,并且每个子组件都必须有权访问注解格式)。

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

2 个答案:

答案 0 :(得分:1)

异步/等待和承诺在语法上基本相同。异步代码,在完成某些工作后将运行一次。

通常,我永远不会在使用Angular时不使用任何一个。 Angular自带RxJS,这远远超出了承诺。作业完成后,您可以使用RxJS运行一次异步代码,但是它也使您可以创建数据流并以多种不同方式对其进行操作。 完全理解RxJS和反应式编程确实需要一点时间,但是一旦您意识到自己可以用它做些什么。

在您的情况下,我喜欢使用运算符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文档,寻找可能有用的东西,如果您找不到任何东西,快速的Google搜索可能总会为您提供解决方案。重点是,不要盲目使用它,而要始终尝试了解它的工作原理。

我希望这是有用的。 :)

编辑:

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

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

答案 1 :(得分:0)

它们有不同的用途。当您要保留编写异步代码的地方时,将使用async / await。 primises是发现执行异步代码并调用回调的地方的工具。