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

Async/Await异步代码异常求助:文件上传后无法执行后续逻辑

问题分析与修复方案

你的代码核心问题出在await与subscribe混用以及嵌套订阅导致的逻辑顺序混乱,具体问题和修复方法如下:

核心问题

  1. await 仅能等待Promise完成,但 subscribe 返回的是RxJS的Subscription对象而非Promise,所以后续的getValidateLog和getLogUpload会在上传请求未完成时直接执行,完全无法等待上传结果。
  2. 嵌套的subscribe让代码逻辑混乱,成功提示的触发依赖getPlan的返回,一旦getPlan请求出错,提示可能无法正常显示。
  3. 代码中的toastRef未定义,运行时会直接报错。

修复后的代码

假设你使用RxJS 7+版本(推荐用lastValueFrom将Observable转为Promise,RxJS 6及以下可使用已废弃的toPromise()),整理后的代码如下:

import { lastValueFrom } from 'rxjs'; // 需要导入该方法

async onSubmit() {
  // 先创建加载中toast并保存引用,避免未定义报错
  const toastRef = this.toastrService.show(
    'loading',
    'MTI - AP Upload File',
    { status: 'loading', duration: 0 } // 加载中不自动关闭
  );

  try {
    // 等待文件上传完成,将Observable转为Promise
    const uploadResponse = await lastValueFrom(this.service.uploadFile(this.requestBody));

    if (uploadResponse.status === 'OK') {
      this.rowData2 = uploadResponse.payload.contents;
      // 等待getPlan请求完成
      await lastValueFrom(this.service.getPlan(this.form.value));
      
      // 显示成功提示
      this.toastrService.show(
        'success',
        'MTI - AP Upload File',
        { status: 'success', duration: 5000 }
      );
      // 获取校验数据与上传日志
      const validateLog = await lastValueFrom(this.service.getValidateLog(this.requestBody.filename));
      const uploadLog = await lastValueFrom(this.service.getLogUpload(this.requestBody.filename));
      // 将日志数据赋值给表格变量,示例:
      // this.validateTableData = validateLog;
      // this.uploadTableData = uploadLog;
    } else {
      this.toastrService.show(
        'error',
        'MTI - AP Upload File',
        { status: 'warning', duration: 5000 }
      );
      await lastValueFrom(this.getLog(this.currentPage, this.paginationPageSize));
    }
  } catch (error) {
    // 统一捕获所有请求失败的情况
    this.toastrService.show(
      'error',
      'MTI - AP Upload File',
      { status: 'error', duration: 5000 }
    );
    console.error('请求出错:', error);
  } finally {
    // 无论成功失败,都关闭toast
    toastRef.close();
  }
}

关键改动说明

  • 用lastValueFrom将每个Observable转为Promise,通过await保证异步操作的执行顺序,避免逻辑混乱。
  • 用try/catch统一处理所有请求的错误情况,防止单个请求失败导致代码卡住。
  • 提前创建并保存toastRef,解决未定义报错的问题,同时用loading状态提示用户上传中。
  • 调整逻辑顺序:上传成功后先完成getPlan请求,再显示成功提示,最后调用日志接口,确保数据全部获取后再展示。
  • 用finally块统一关闭toast,减少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:22:40