前言
我在开发公司项目的时候,有这样一个页面的下拉框数组,是公司内七八个部门的同事数据组合而成。
于是我在最开始的时候,就通过调用获取某个指定部门ID下所有同事接口来获取数据,并通过一个常量数组一个一个push进去,例如:
// 获取运营人员下拉
this.devMangeService.getUserList('23').subscribe(res => {
const data = res['data'];
data.forEach(index => {
this.yyList.push(index);
});
});
this.devMangeService.getUserList('39').subscribe(res => {
const data = res['data'];
data.forEach(index => {
this.yyList.push(index);
});
});
// ……省略中间7个
this.devMangeService.getUserList('107').subscribe(res => {
const data = res['data'];
data.forEach(index => {
this.yyList.push(index);
});
});
是不是头都看大了?
这是我刚入职的时候写的代码(比较笨比),其实通过
this.yyList=[...res['data']]会更简洁易用一些
但你知道的,我的代码洁癖不允许我有如此臃肿且重复的代码,这样不优雅!
于是我便去查了查资料,试图找到一种能够将代码精简化的方式,没想到还真有。
那就是RxJS操作符:forkJoin
forkJoin是什么
官方定义
Accepts an
ArrayofObservableInputor a dictionaryObjectofObservableInputand returns anObservablethat emits either an array of values in the exact same order as the passed array, or a dictionary of values in the same shape as the passed dictionary.
通俗定义
简单来说,forkJoin 是 RxJS 中的一个操作符,用于并行执行多个Observable,并在所有 Observable都完成后,以数组的形式返回最终值。
也就是说,当你有重复执行Observable或等待多个Observable都执行完成才进行下一步的时候,就可以使用forkJoin 操作符了。对于我这样要调用多个查询ID的接口的使用场景实在是太合适了。
除了RxJS,JAVA中也有
forkJoin的存在,用于实现高并发的使用场景,在这里不多赘述。
具体实现
信息集合
我所执行的Observable中,只有部门ID是不同的,那么我便可以将部门ID整合为一个数组,用于并行调用:
const ids = ['23', '39', '41', '67', '73', '95', '101', '103', '105', '107'];
创建请求列表
目前已经有了需要查询的部门ID,那就可以为每个ID创建一个Observable请求,使用map函数生成一个请求列表:
const requests = ids.map((id) => this.devemange.getUserList(id));
使用forkJoin并行处理
接下来使用今天的主角:forkJoin,来执行我们已经写好的请求列表。
这次我就使用扩展运算符来代替
push方法,使得代码更加精简
forkJoin(requests).subscribe(responses => {
responses.forEach((res:any) => {
this.yyList.push(...res['data']); // 使用扩展运算符
});
});
到这一步,我就通过使用forkJoin操作符,生成了一段精简、易维护、性能提升且优雅的代码获取了我想要的yyList数组。
另一个使用场景
由于我上述的使用场景是重复执行Observable,缺少了等待多个Observable都执行完成才进行下一步该场景,于是我写了一个简单的demo来演示一下:
import { Component, OnInit } from '@angular/core';
import { forkJoin } from 'rxjs';
import { DataService } from '../../services/data.service';
@Component({
selector: 'demo',
})
export class DemoComponent implements OnInit {
constructor(private dataService: DataService) {}
ngOnInit() {
// 使用 forkJoin 聚合请求
forkJoin({
user: this.dataService.getUserData(),
orders: this.dataService.getOrderData(),
inventory: this.dataService.getInventoryData(),
sales: this.dataService.getSalesData(),
analytics: this.dataService.getAnalyticsData(),
}).subscribe({
next: (results) => {
// 获取results结果
console.log('获取数据:', results);
},
error: (err) => console.error('失败:', err),
complete: () => {
console.log('整个流程完成');
},
});
}
}