为何在map中调用async函数返回Promise<void>而非Promise<File>
问题分析与解决
核心问题出在downloadFiles函数里的extra_photos.map回调:你只在异步回调里执行了await downloadFile,但没有返回这个调用的结果,所以每个回调函数的返回值是undefined,对应的Promise类型就是Promise<void>,整个map得到的是Promise<void>[],最终赋值给filesExtraPhoto(类型为File[])时就会出现类型不匹配的错误。
另外,你把Promise<void>[]直接放进外层的Promise.all里,外层Promise.all会把这个数组当成单个Promise元素处理,await之后得到的还是void[],这也不是你需要的File[]。
修复方案
步骤1:让map返回正确的Promise
把extra_photos.map的回调改成直接返回downloadFile的调用结果,不需要额外的async/await(因为downloadFile本身就返回Promise):
this.extra_photos.map(photo => this.downloadFile(photo.id, photo.name))
如果一定要用async/await(比如需要额外处理逻辑),必须手动返回结果:
this.extra_photos.map(async (photo) => { // 可以在这里加额外逻辑 return await this.downloadFile(photo.id, photo.name); })
步骤2:用Promise.all包裹extra_photos的下载请求
因为map返回的是Promise<File>[],需要用Promise.all把这个数组转换成Promise<File[]>,这样外层Promise.all await之后,res[3]就是File[],能直接赋值给filesExtraPhoto。
完整修正后的代码
async downloadFiles() { const res = await Promise.all([ this.view1 ? this.downloadFile(this.view1.id, this.view1.name) : null, this.view2 ? this.downloadFile(this.view2.id, this.view2.name) : null, this.view3 ? this.downloadFile(this.view3.id, this.view3.name) : null, // 这里用Promise.all包裹map的结果,得到Promise<File[]> Promise.all(this.extra_photos.map(photo => this.downloadFile(photo.id, photo.name) )) ]); this.fileView1 = res[0] ?? undefined; this.fileView2 = res[1] ?? undefined; this.fileView3 = res[2] ?? undefined; // 现在res[3]是File[],类型匹配 this.filesExtraPhoto = res[3]; }
额外优化:简化downloadFile函数
你重写后的downloadFile已经很简洁了,还可以再优化掉不必要的变量:
async downloadFile(id: number, name: string): Promise<File> { const { data } = await axios({ url: `/file/${id}`, method: "GET", responseType: "blob", }); return new File([data], name); }
内容的提问来源于stack exchange,提问作者Nikita
相关产品推荐
相关产品推荐

