为什么我的JS API客户端逐行返回文件而非导出单个CSV文件?
问题核心原因
你当前的问题本质是两点:
- 下载逻辑写在单条接口请求的回调里,每请求1个ID就触发1次下载,自然会出现多次下载、每次只有1行数据的问题
- 之前你直接在
forEach后调用下载函数报错,是因为fetch是异步请求,调用下载函数时所有接口还没返回结果,拿不到完整的行数据,同时还存在变量作用域不匹配的问题
完整修改方案
// 读取文件返回所有行内容 function readFileLines(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = e => resolve(e.target.result.split(/\r|\n|\r\n/)); reader.onerror = reject; reader.readAsText(file); }); } // 封装单条ID的接口请求,仅返回格式化后的单行数据 function getRelease(idFiltered) { return fetch(`https://api.*******.com/releases/${idFiltered}`, { headers: { 'User-Agent': '*******/0.1' } }) .then(res => res.json()) .then(data => { if (data.message === 'Release not found.') { return [idFiltered, '', '', 'Release not found', '', '', '']; } const artists = data.artists?.map(artist => artist.name).join('、') || ''; const country = data.country || 'Unknown'; const released = data.released_formatted || 'Unknown'; const genres = data.genres?.join('、') || ''; const styles = data.styles?.join('、') || ''; const tracklist = data.tracklist?.map(track => track.title).join('、') || ''; return [idFiltered, artists, country, released, genres, styles, tracklist]; }); } // 统一下载函数 function downloadCsv(rows) { const ROW_NAMES = ["Release ID", "artists", "country", "released", "genres", "styles", "tracklist"]; // 加BOM头解决Windows Excel打开中文乱码问题 const csvContent = "data:text/csv;charset=utf-8,\ufeff" + ROW_NAMES.join(',') + '\n' + rows.map(row => row.join(',')).join('\n'); const link = document.createElement('a'); link.href = encodeURI(csvContent); link.download = 'my_data.csv'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } // 文件选择事件监听 document.getElementById('fileInput').addEventListener('change', async function(e) { const file = e.target.files[0]; if (!file) return; try { const lines = await readFileLines(file); const idFiltered = lines.filter(v => v.trim() !== ''); // 等待所有接口请求完成,拿到全量行数据 const allRows = await Promise.all(idFiltered.map(id => getRelease(id))); // 一次性触发下载 downloadCsv(allRows); } catch (err) { console.error('执行失败:', err); } });
关键调整说明
- 移除了
getRelease里的下载逻辑,仅保留接口请求和单条数据格式化的逻辑,数组类型字段提前转成字符串避免CSV列错位 - 用
Promise.all批量处理所有异步请求,等所有请求返回后再统一调用下载函数,保证只生成1份包含全量数据的CSV - 用
async/await简化异步逻辑,避免嵌套回调 - 所有变量添加声明关键字,避免隐式全局变量导致的作用域冲突
- CSV内容添加
\ufeffBOM头,解决Windows系统下Excel打开中文乱码的问题
内容的提问来源于stack exchange,提问作者double-happiness
相关产品推荐
相关产品推荐

