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

使用FileReader读取上传图片时外部console.log值不匹配如何解决

问题原因

FileReader的readAsDataURL以及对应的onload回调是异步执行的:你调用reader.readAsDataURL(file)之后,浏览器不会等待文件读取完成,会直接继续往下执行后面的console.log("out", this.imgArrayy)代码,这时候onload回调还没触发,this.imgArrayy还没被赋值为当前选中文件的字节数组,就会出现你看到的现象:

  • 第一次选图:out打印时this.imgArrayy还没被赋值过,所以输出undefined,等onload触发后才给this.imgArrayy赋第一张图的值
  • 第二次选图:out打印时onload还没处理第二张图,this.imgArrayy存的还是第一次赋值的第一张图结果,所以打印上一张的字节数组,等onload触发后才更新为第二张的结果

解决方案

方案1:直接在onload回调中处理业务逻辑

所有需要用到当前图片字节数组的操作,都放到onload回调内部执行,就能保证拿到的是当前最新的结果:

upload(files: any) {
  const file = files.files[0];
  if (!file) return;
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = (event) => {
    this.url = reader.result as string;
    const base64Index = this.url.indexOf(';base64,') + ';base64,'.length;
    const base64 = this.url.substring(base64Index);
    const raw = window.atob(base64);
    const rawLength = raw.length;
    const imgArray = new Uint8Array(new ArrayBuffer(rawLength));
    for (let i = 0; i < rawLength; i++) {
      imgArray[i] = raw.charCodeAt(i);
    }
    this.imgArrayy = imgArray;
    console.log("当前图片字节数组:", this.imgArrayy);
    // 所有需要用到imgArrayy的业务逻辑都写在这里
    // 比如上传请求、本地预览等操作
  };
}

方案2:用Promise封装实现async/await调用

如果需要在upload函数外部拿到结果,可以把文件读取逻辑封装成Promise,调用时用await等待异步操作完成:

// 封装文件读取为字节数组的通用方法
getFileByteArray(file: File): Promise<Uint8Array> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = (event) => {
      const url = reader.result as string;
      const base64Index = url.indexOf(';base64,') + ';base64,'.length;
      const base64 = url.substring(base64Index);
      const raw = window.atob(base64);
      const rawLength = raw.length;
      const imgArray = new Uint8Array(new ArrayBuffer(rawLength));
      for (let i = 0; i < rawLength; i++) {
        imgArray[i] = raw.charCodeAt(i);
      }
      resolve(imgArray);
    };
    reader.onerror = (error) => reject(error);
  });
}

// 改造upload方法为异步方法
async upload(files: any) {
  const file = files.files[0];
  if (!file) return;
  this.imgArrayy = await this.getFileByteArray(file);
  this.url = URL.createObjectURL(file); // 也可以直接用这个方法生成预览链接,不需要自己转base64
  console.log("out", this.imgArrayy); // 这里就能拿到当前最新的字节数组了
  // 后续业务逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:51:03