文章内容

2023/11/22 5:19:26,作 者: 黄兵

如何使用ForkJoin — Angular示例

ForkJoin是一个常用的 RxJS 操作符,用于将多个 Observables 合并为一个单一的 Observable。

最近,我遇到了将几个 Observables 合并为一个包含每个流结果的单一流的需求。

具体而言,在我的情况下,我需要将来自多个HTTP调用的结果(在Angular中是Observables)合并为一个单一的Observable。

经过一些尝试,我得出结论,forkJoin是完成这项任务的正确工具。


文章中的有趣内容清单:

  1. 如何使用forkJoin — Angular示例: 文章介绍了如何在Angular中使用forkJoin的例子。

  2. 一个更实际的例子和StackBlitz: 文章提供了一个更为实际的例子,并给出了在StackBlitz上查看更好实现的链接。

  3. 已弃用的语法: 文章可能涉及到已被弃用的语法,这对于需要保持最新实践的读者来说是关键信息。

  4. 操作符决策树: 文章中可能包含有关何时使用forkJoin相对于其他RxJS操作符的决策指导。

  5. 什么是forkJoin forkJoin是一个RxJS操作符,它“等待 Observables 完成,然后组合它们发出的最后值”。换句话说,forkJoin允许你等待多个 Observables 完成,然后将它们最新的值作为数组发出。

  6. forkJoin的用途: 可以用来合并多个 HTTP 请求的结果,当它们全部完成时,再发出这些结果。

  7. 如何使用forkJoin — Angular示例: 如果你匆忙的话,文章提供了一个快速的实现示例。然而,作者鼓励你阅读下面的解释,或在StackBlitz上查看更好的实现。

这些内容涵盖了文章中的重要主题,包括实际示例、已弃用的语法警示、操作符的选择指南以及forkJoin的基本概念。

...

export class App implements OnInit {
  sources = [
    this.http.get('https://jsonplaceholder.typicode.com/users/1'),
    this.http.get('https://jsonplaceholder.typicode.com/users/2'),
    this.http.get('https://jsonplaceholder.typicode.com/users/3'),
  ];

  constructor(private http: HttpClient) {}

  ngOnInit() {
    forkJoin(this.sources).subscribe(console.log);
  }
}

sources数组包含通过三个使用Angular服务的HTTP调用创建的三个Observables。

forkJoin操作符接受一个Observable数组,因此我们传入sources数组。

当数组传递给forkJoin时,该操作符等待每个Observable(HTTP调用)完成。

然后,它将每个调用的最后一个值合并为一个单一的Observable。

我们订阅这个Observable,并在控制台中记录数据。

更实际的例子

我上面展示的在书本中效果很好,但在现实生活中,事情往往变得更加复杂一些。

一个非常常见的情况涉及到需要操作数据和一些错误处理。我们将对它们进行一番探讨。

操作数据

大多数时候,后端返回的数据在前端需要进行一些处理。

在使用forkJoin时,我们需要记住forkJoin操作符“返回一个Observable,该Observable发出一个与传递的数组完全相同顺序的值数组”。

扩展我们的例子,我们可以使用map操作符来转换发出的值。

map操作符以包含通过传递给forkJoin的三个Observables发出的最新值的数组作为输入,并返回一个新对象,该对象具有三个属性,userOneuserTwouserThree,这些属性对应于每个Observables发出的最新值。

forkJoin(this.sources)
      .pipe(
        map(([userOne, userTwo, userThree]) => {
          return {
            userOne: userOne,
            userTwo: userTwo,
            userThree: userThree,
          };
        })
      )
      .subscribe(console.log);

上面报告的冗长语法可以简化如下:

  1. 如果返回的对象在同一行开始,可以去掉return关键字。
  2. 如果值的名称与键相同,可以不重复在对象中赋值。
 forkJoin(this.sources)
      .pipe(
        map(([userOne, userTwo, userThree]) => ({
          userOne,
          userTwo,
          userThree,
        }))
      )
      .subscribe(console.log);

最后,我们可以通过使用对象解构和更新值来在map操作符中操作数据。

map(([userOne, userTwo, userThree]) => ({
  userOne: { ...userOne, name: 'Lorenzo' },
  userTwo,
  userThree,
}))

基本错误处理

根据上下文和你能采取的措施,有几种错误处理策略。

然而,它们都利用catchError操作符,该操作符捕捉源Observable中的错误,并通过返回一个新的Observable或抛出一个错误来适当地处理它们。

下面的例子扩展了代码,以便如果发生错误,catchError操作符将捕捉到它并返回一个新的Observable。

forkJoin(this.sources)
  .pipe(
    map(([userOne, userTwo, userThree]) => ({
      userOne: { ...userOne, name: 'Lorenzo' },
      userTwo,
      userThree,
    })),
    catchError((error) => of({ error }))
  )

of操作符只是一个占位符。你可以使用发出的错误值来通知用户,将错误发送到服务器或第三方,或采取其他操作,比如记录错误。

已弃用的语法

只是一个小小的警告。

在许多示例中,你会看到如下的语法。

forkJoin(
  this.http.get('https://jsonplaceholder.typicode.com/users/1'),
  this.http.get('https://jsonplaceholder.typicode.com/users/2'),
  this.http.get('https://jsonplaceholder.typicode.com/users/3')
)

这种语法已经被弃用。如文档所述,直接将Observables作为参数传递的做法已经被弃用。

这被称为“rest-parameter signature”,并且将在 RxJS v8 中被移除。

RxJS建议像我们在上面的例子中所做的那样,传递一个源Observables的数组。

// From RxJS

// deprecated
forkJoin(odd$, even$);
// suggested change
forkJoin([odd$, even$]);
// or
forkJoin({odd: odd$, even: even$})

操作符决策树

如果你不熟悉RxJS操作符决策树,你应该查看一下。它将帮助你找到或选择适合你需求的最佳操作符。



文章来源:How To Use ForkJoin — Angular Example


其他相关推荐:

1、node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected.

2、Angular - “has no exported member 'Observable'”

3、Can't resolve all parameters for TypeDecorator: (?).

4、前端工程研究:理解函式編程核心概念與如何進行 JavaScript 函式編程

5、Angular subscribe loading

分享到:

发表评论

评论列表