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

Angular中customerTasks数组显示3个元素但仅能获取1个的问题求助

问题描述

从服务器获取数据时使用Promise等待返回,当前遇到异常:从某页面返回至另一页面后,用于向其他组件传递客户任务的tasks数组,控制台打印显示包含3个SelectedCustomerTasks元素,但调用findTasksOfCustomer查找选中客户对应元素时,仅能得到一个元素。

控制台输出情况

在findTasksOfCustomer函数中打印this.customerTasks:

0: {customerId: '418', tasks: Array(1), openTasksAmount: 1}
1: {customerId: '503', tasks: Array(1), openTasksAmount: 1}
2: {customerId: '409', tasks: Array(4), openTasksAmount: 3}

但遍历该数组时,控制台仅输出:

{customerId: '418', tasks: Array(1), openTasksAmount: 1}

相关代码

loadTasks函数

private loadTasks() {
  return new Promise((resolve, reject) => {
    var tasks: tasks[] = [];

    this.customers.forEach(async (customer, index) => {
      var tasks = (
        await this._taskClient.getCustomerTasks(customer.customerId).toPromise()
      ).map((x) => JSON.parse(x) as Task);

      var data: SelectedCustomerTasks = {
        customerId: customer.customerId,
        tasks: tasks,
        openTasksAmount: tasks.filter(
          (x) => x.output[0].valueBoolean !== true
        ).length,
      };

      tasks.push(data);

      if (index == this.customers.length - 1) {
        resolve(tasks);
      }
    });
  });
}

ngOnInit方法

public ngOnInit() {
  this.loadTasks().then((tasks: SelectedCustomerTasks[]) => {
    if (tasks.length > 0) {
      this.customerTasks = tasks;
      if (sessionStorage.getItem("customerId")) {
        this.selectedCustomer = this.customers.find(
          (x) => x.customerId == sessionStorage.getItem("customerId")
        );
        if (this.selectedCustomer) {
          this.emitCustomerData(this.selectedCustomer, false);
        }
      }
    }
  });
}

emitCustomerData与findTasksOfCustomer函数

private async emitCustomerData(customer: Customer){
 this.selectedCustomerEvent.emit(this.findTasksOfCustomer(customer));
}

private findTasksOfCustomer(customer: Customer): SelectedCustomerTasks {
  return this.customerTasks.find((x) => x.customerId == customer.customerId );
}

问题原因与修复方案

核心问题:异步逻辑处理错误

  1. forEach不支持异步等待:forEach会直接启动所有异步请求,不会等待前一个请求完成再执行下一个,导致你判断index == this.customers.length - 1时,前面的异步请求大概率还没完成,此时resolve出去的数组只有最后一个客户的数据。后续其他请求完成后再往数组里push数据,控制台打印的是补全后的数组,但你第一次查找时用的是不完整的数组。
  2. 变量名冲突:循环内重新声明了var tasks,直接覆盖了外层用来收集所有客户任务的数组,导致外层数组根本没被正确填充。

修复步骤

方案1:用for...of实现串行异步请求

替换forEach为支持异步等待的for...of,同时修正变量名冲突:

private async loadTasks() {
  const tasks: SelectedCustomerTasks[] = [];

  for (const customer of this.customers) {
    // 修改变量名,避免和外层数组冲突
    const customerTasks = (
      await this._taskClient.getCustomerTasks(customer.customerId).toPromise()
    ).map((x) => JSON.parse(x) as Task);

    const data: SelectedCustomerTasks = {
      customerId: customer.customerId,
      tasks: customerTasks,
      openTasksAmount: customerTasks.filter(
        (x) => x.output[0].valueBoolean !== true
      ).length,
    };

    tasks.push(data);
  }

  return tasks;
}

同步修改ngOnInit调用:

public async ngOnInit() {
  const tasks = await this.loadTasks();
  if (tasks.length > 0) {
    this.customerTasks = tasks;
    const storedCustomerId = sessionStorage.getItem("customerId");
    if (storedCustomerId) {
      this.selectedCustomer = this.customers.find(
        (x) => x.customerId === storedCustomerId
      );
      if (this.selectedCustomer) {
        this.emitCustomerData(this.selectedCustomer);
      }
    }
  }
}

方案2:用forkJoin实现并行异步请求(性能更优)

如果不需要串行请求,建议用forkJoin同时发起所有请求,等待全部完成后返回完整数组:

private loadTasks() {
  const taskObservables = this.customers.map(customer => 
    this._taskClient.getCustomerTasks(customer.customerId).pipe(
      map(tasks => {
        const parsedTasks = tasks.map(x => JSON.parse(x) as Task);
        return {
          customerId: customer.customerId,
          tasks: parsedTasks,
          openTasksAmount: parsedTasks.filter(x => !x.output[0].valueBoolean).length
        } as SelectedCustomerTasks;
      })
    )
  );

  return forkJoin(taskObservables).toPromise();
}

额外优化

  • 用===替代==进行全等判断,避免类型转换导致的潜在问题。
  • emitCustomerData内无异步操作,可去掉async关键字。

内容的提问来源于stack exchange,提问作者user22114465

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:52:35