为何在.find方法中变量始终返回undefined?
问题分析与解决方案:
schoolAndGradeLevelId 始终返回undefined 核心问题根源
你的代码中存在异步操作时序错误:
fetchShcoolAndGradeLevelId内部通过RxJS Observable发起API请求,属于异步操作。调用该方法后立即执行this.schoolAndGradeLevelIds.find()时,API请求还未完成,this.schoolAndGradeLevelIds数组尚未更新,因此找不到对应数据,导致schoolAndGradeLevelId始终为undefined。- 遍历学生数据时同步触发异步请求,会导致请求并发,且无法保证在添加学生记录前获取到返回结果。
解决方案
通过调整异步操作的处理逻辑,确保在获取到学校和年级ID后再处理学生数据:
1. 修改fetchShcoolAndGradeLevelId方法,使其返回Observable
private fetchShcoolAndGradeLevelId( schoolName: string, gradeLevelName: string ): Observable<{ schoolId: number; gradeLevelId: number; schoolName: string; gradeLevelName: string }> { return this.queriesHandler.handle( new GetSchoolAndGradeLevelIdByNameQuery(schoolName, gradeLevelName) ).pipe( map(res => { const data = { ...res.data[0], schoolName, gradeLevelName }; this.schoolAndGradeLevelIds.push(data); return data; }) ); }
2. 重构loadFile方法,使用async/await处理异步请求
import { firstValueFrom } from 'rxjs'; private async loadFile(): void { let fileReader = new FileReader(); fileReader.readAsBinaryString(this.file); fileReader.onload = async (e) => { const excel = <string>fileReader.result; const rawStudents = parseImportedStudents(excel); // 去重学校+年级组合,避免重复发起API请求 const uniquePairs = Array.from( new Set(rawStudents.map(s => `${s.schoolName}-${s.gradeLevelName}`)) ).map(pair => pair.split('-')).map(([school, grade]) => ({ schoolName: school, gradeLevelName: grade })); // 批量获取所有需要的ID,等待所有请求完成 await Promise.all( uniquePairs.map(async ({ schoolName, gradeLevelName }) => { const exists = this.schoolAndGradeLevelIds.some( s => s.schoolName === schoolName && s.gradeLevelName === gradeLevelName ); if (!exists) { await firstValueFrom(this.fetchShcoolAndGradeLevelId(schoolName, gradeLevelName)); } }) ); // 所有ID已加载,处理学生数据 rawStudents.forEach((student) => { const schoolAndGradeLevelId = this.schoolAndGradeLevelIds.find( (s) => s.schoolName === student.schoolName && s.gradeLevelName === student.gradeLevelName ); this.students.push({ studentName: student.studentName, gradeLevelName: student.gradeLevelName, schoolName: student.schoolName, documentNumber: student.documentNumber, birthDate: student.birthDate, schoolId: schoolAndGradeLevelId?.schoolId, gradeLevelId: schoolAndGradeLevelId?.gradeLevelId, }); }); }; }
关键修改说明
- 将异步请求转换为Promise,通过
async/await确保所有ID请求完成后再处理学生数据。 - 对学校和年级组合去重,减少重复API请求,提升性能。
- 使用严格相等符
===替换==,避免潜在的类型转换错误。
内容的提问来源于stack exchange,提问作者Eduardo Caversan
相关产品推荐
相关产品推荐

