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

Vue+JavaScript多JSON文件上传解析结果异常排查

问题根因

你的代码存在两个核心问题,导致多文件解析结果异常:

  • 变量作用域错误:循环中使用var声明i和reader,二者都是函数级作用域,整个循环共用同一个变量引用。FileReader.onload是异步回调,等回调触发时for循环早已执行完毕,此时i已经是循环结束后的终值,reader也指向最后一轮循环创建的FileReader实例,所有回调都会写入错误索引、重复读取最后一个文件的内容。
  • 初始数据结构不匹配:你将存储结果的this.data初始化为空对象{}而非数组,结合异步回调的写入时序不确定,很容易出现空索引、值覆盖的问题。
修复后代码

文件选择控件不需要改动,只需要调整TS逻辑即可,核心修改是把循环内的var替换为块级作用域的let,同时将this.data初始化为数组存储多份结果:

showfiles() {
  // 初始化为数组,按索引存储每个文件的解析结果
  this.data = []
  const files = (this.$refs.fileSelect as HTMLInputElement).files
  if (!files || files.length === 0) return

  for (let i = 0; i < files.length; i++) {
    // let是块级作用域,每轮循环都会生成独立的i、reader绑定,不会互相覆盖
    const reader = new FileReader()
    reader.onload = () => {
      try {
        this.data[i] = JSON.parse(reader.result as string)
      } catch (err) {
        console.error(`第${i+1}个JSON文件解析失败:`, err)
      }
    }
    reader.readAsText(files[i])
  }
}

可选优化:等待所有文件解析完成

如果需要在所有文件都解析完毕后执行后续逻辑,可以结合Promise.all封装读取逻辑,保证结果顺序和文件选择顺序完全一致:

async showfiles() {
  const files = (this.$refs.fileSelect as HTMLInputElement).files
  if (!files || files.length === 0) return

  const filePromises = Array.from(files).map(file => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = () => {
        try {
          resolve(JSON.parse(reader.result as string))
        } catch (err) {
          reject(err)
        }
      }
      reader.onerror = reject
      reader.readAsText(file)
    })
  })

  try {
    // 所有文件解析完成后统一赋值给this.data
    this.data = await Promise.all(filePromises)
    // 后续业务逻辑可在此处编写
  } catch (err) {
    console.error('文件解析失败:', err)
  }
}

内容的提问来源于stack exchange,提问作者harsh panday

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:45:42