Angular中高效为Array.map生成的对象数组添加系统URL
高效实现Angular表格的两次网络请求数据合并
嘿,我明白你现在的需求:通过两次请求构建表格数据,第一次拿文档类型和关联系统,第二次给每个文档类型匹配对应系统的URL,之前的实现不仅报了undefined错误,效率还不高。我来给你梳理下优化方案~
先说说之前的错误原因
你遇到的Error: undefined is not an object,大概率是用索引遍历数组时,某个索引对应的元素不存在(比如数组长度变化、异步请求时序问题导致数组未正确初始化),或者在匹配系统时,找不到对应的元素就直接赋值,导致modDocTypes[i_1]变成了undefined。不过既然你已经修正了属性添加的问题,咱们重点聊怎么让这个流程更高效。
高效优化方案:减少请求次数+快速映射
核心思路是先对系统去重,批量请求URL,再用映射表快速匹配,避免给每个文档类型都发一次请求(数据量大时请求次数会爆炸)。具体步骤如下:
1. 提取唯一系统,减少请求量
从第一次请求返回的文档类型数组中,提取所有不重复的系统名称——用Set就能轻松实现,这样请求次数就从文档类型的数量变成了唯一系统的数量,大大减少网络请求开销。
2. 批量请求系统URL
用RxJS的forkJoin(或者Promise.all)批量发起这些唯一系统的URL请求,等待所有请求完成后再处理数据。
3. 构建系统-URL映射表
把返回的URL数据转换成Map(或者普通对象),这样后续给每个文档类型匹配URL时,只需要O(1)的查找时间,比循环匹配的O(n)高效太多。
4. 生成最终表格数据
遍历原始文档类型数组,通过映射表快速获取对应URL,添加到每个对象中即可。
Angular代码示例
import { forkJoin, switchMap } from 'rxjs'; // 假设你有对应的服务 import { DocumentService } from './document.service'; import { SystemService } from './system.service'; // ... 组件类内部 this.documentService.getDocTypes().pipe( switchMap(docTypes => { // 第一步:提取所有唯一的系统名称 const uniqueSystems = [...new Set(docTypes.map(doc => doc.System))]; // 第二步:批量创建URL请求,同时关联系统名称和URL const urlRequests = uniqueSystems.map(system => this.systemService.getSystemUrl(system).pipe( map(url => ({ system, url })) ) ); // 等待所有URL请求完成,然后处理数据 return forkJoin(urlRequests).pipe( map(urlResults => { // 第三步:构建系统到URL的映射表 const systemUrlMap = new Map(urlResults.map(item => [item.system, item.url])); // 第四步:给每个文档类型添加URL属性 return docTypes.map(doc => ({ ...doc, SystemLocation: systemUrlMap.get(doc.System) })); }) ); }) ).subscribe(finalTableData => { this.tableData = finalTableData; });
为什么这个方案更高效?
- 减少网络请求:比如你示例里的3个文档类型对应2个唯一系统,请求次数从3次降到2次,数据量越大,节省的请求越多;
- 快速查找:用
Map做URL匹配是O(1)时间复杂度,遍历文档数组是O(n),整体时间复杂度远低于嵌套循环匹配的O(n*m); - 代码更安全:避免了索引操作,从根源上减少
undefined错误的可能性。
内容的提问来源于stack exchange,提问作者cfoster5
相关产品推荐
相关产品推荐

