Async/Await异步代码异常求助:文件上传后无法执行后续逻辑
问题分析与修复方案
你的代码核心问题出在await与subscribe混用以及嵌套订阅导致的逻辑顺序混乱,具体问题和修复方法如下:
核心问题
await仅能等待Promise完成,但subscribe返回的是RxJS的Subscription对象而非Promise,所以后续的getValidateLog和getLogUpload会在上传请求未完成时直接执行,完全无法等待上传结果。- 嵌套的
subscribe让代码逻辑混乱,成功提示的触发依赖getPlan的返回,一旦getPlan请求出错,提示可能无法正常显示。 - 代码中的
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
相关产品推荐
相关产品推荐

