You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 06:27:49