在Promise.allSettled中调用fetch返回空值,无法获取图片Base64数组
问题分析与修复方案
核心问题
- Promise.allSettled未等待异步操作完成:
results.map的async回调里嵌套了立即执行的async函数,但既没返回也没await这个函数,导致map生成的Promise会立即resolve,Promise.allSettled不等内部fetch请求完成就继续执行,最终response.img还没填充就被返回。 - fetchTiff函数冗余嵌套:在Promise内部套async立即执行函数属于多余写法,易造成逻辑混乱。
- 数组填充方式不可控:直接在异步回调里push外部数组,不如让每个Promise返回处理结果后统一收集,逻辑更清晰。
修复后的代码
主函数部分
(async function getData() { results = results.recordset; // 用Promise.allSettled等待所有异步请求完成 const settledResults = await Promise.allSettled(results.map(async (record) => { // 去掉嵌套的立即执行async函数,直接在当前回调处理逻辑 const file = record.Path.split('Images'); const file_path = file[1].replaceAll('\\', '/') + "/" + record.FileName; const img_url = "localhost" + file_path; const file_data_response = await reportModel.fetchTiff(img_url); const base64Image = Buffer.from(file_data_response, 'binary').toString('base64'); const imgSrc = "data:png;base64," + base64Image; // 改用生成的base64地址,符合需求 const imgImg = `<img src='${imgSrc}' alt="Remote Image" />`; // 返回处理后的img标签,而非直接修改外部数组 return imgImg; })); // 统一收集成功的结果到response.img response.img = settledResults .filter(item => item.status === 'fulfilled') .map(item => item.value); return resolve(response); })();
fetchTiff函数简化
exports.fetchTiff = async function(image_url) { // 直接用async函数返回Promise,消除冗余嵌套 const responsezz = await fetch(image_url); const blob = await responsezz.blob(); // Node环境下需将Blob转为ArrayBuffer再转Buffer,浏览器环境可直接用blob const arrayBuffer = await blob.arrayBuffer(); return Buffer.from(arrayBuffer); };
关键说明
- 移除map回调里的嵌套async立即执行函数,让
results.map生成的每个Promise真正绑定fetch请求的异步流程,确保Promise.allSettled能等待所有请求结束。 - fetchTiff简化为async函数,直接返回处理后的Buffer,避免Promise嵌套带来的逻辑混乱。
- 不再直接在异步回调中修改外部数组,而是通过
Promise.allSettled的结果统一收集成功的img标签,逻辑更清晰、易维护。 - 修正原代码中
imgImg使用原始img_url的问题,改为使用生成的base64地址,匹配你获取图片Base64编码存入数组的需求。
内容的提问来源于stack exchange,提问作者dishank goyal
相关产品推荐
相关产品推荐

