首页 > 解决方案 > 使用 async/await 意外执行代码

问题描述

我正在尝试将 localhost URL 数组转换为 base64 字符串。

    let uploadedBase64Images = [];
    for (let i = 0; i < urls.length; i++) {
      let img = await fetch(urls[i]);
      let imgBlob = await img.blob();
      let reader = new FileReader();
      
      let base64;
      reader.readAsDataURL(imgBlob);
      reader.onloadend = () => {
        console.log(reader.result)
        base64 = reader.result;
        console.log(base64)
        uploadedBase64Images.push(base64)
      };
    } 

    console.log(uploadedBase64Images)

我注意到的一件事是console.log(uploadedBase64Images)总是打印 before console.log(base64)。此代码块也包含在异步函数中。我尝试了许多其他方法,但在一天结束时,uploadedBase64Images总是空的。

当我移出uploadedBase64Images.push(base64)reader.onloadend,即:

    reader.onloadend = () => {
        console.log(reader.result)
        base64 = reader.result;
        console.log(base64)
    };
    uploadedBase64Images.push(base64)

uploadedBase64Images[undefined],这让我相信 Promise 没有得到解决?

感谢您对此的任何帮助,在此先感谢!

标签: javascript

解决方案


据我所知,问题在于reader.onloadend,它在自己的区域中,没有遵循异步行为。

因此,通过将 reader 函数包装到 Promise 以在执行任何操作之前等待其响应可能会解决您的问题

// wrapping reader in Promise
const convertImageToBase64 = async(imgBlob) => {
  return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(imgBlob);
      reader.onloadend = () => {
        resolve(reader.result);
      };
      reader.onerror = reject
  })
}

const uploadedBase64Images = [];
for (let i = 0; i < urls.length; i++) {
  const img = await fetch(urls[i]);
  const imgBlob = await img.blob();
  const base64 = await convertImageToBase64(imgBlob)
  uploadedBase64Images.push(base64)
} 
console.log(uploadedBase64Images)

推荐阅读