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

为什么我的JS API客户端逐行返回文件而非导出单个CSV文件?

问题核心原因

你当前的问题本质是两点:

  1. 下载逻辑写在单条接口请求的回调里,每请求1个ID就触发1次下载,自然会出现多次下载、每次只有1行数据的问题
  2. 之前你直接在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 11:36:03