【问题标题】:User Object gets excecuted before the compressed picture gets saved, how can i change that?用户对象在压缩图片保存之前被执行,我该如何更改?
【发布时间】:2021-08-13 12:12:30
【问题描述】:

我有问题。我想压缩图像并将其存储到本地主机中。问题是image.onload是在对象创建后执行的

            var oneUser = {
              id: user.user.id_profile,
              username: user.user.username,
              image: user_image,
            };
            users.push(oneUser);

我尝试使用关键字await,但不幸的是它不起作用。如何将压缩 blob url 保存到本地存储具有 blob url 的用户对象中。

const getChat = () => {
    axios
      .get(`http://localhost:4000/chat/rooms/${chatid}`, {})
      .then((res) => {
        if (res.status === 200) {
          
          var users = [];
          res.data.users.map((user) => {

            // BASE64 zu Blob URL
            var user_image = "";
            image =  user.user.image.split(",");
            image = image[1]
            const contentType = 'image/png';
            const b64Data = image;
            const blob = b64toBlob(b64Data, contentType);
            const blobUrl = URL.createObjectURL(blob);
            console.log(blobUrl)
            // Blob komporemieren
            var image = new Image();
            image.src = blobUrl;
            image.onload = function() {
               var  resized =  resizeMe(image); // resized image url
               // BASE64 zu Blob Url
              resized = resized.split(",");
              resized = resized[1]
              const contentType = 'image/png';
              const b64Data = resized;
              const blob = b64toBlob(b64Data, contentType);
              user_image = URL.createObjectURL(blob);
              console.log(user_image)
            }
  
            
            console.log(user_image)
            var oneUser = {
              id: user.user.id_profile,
              username: user.user.username,
              image: user_image,
            };
            users.push(oneUser);
          });
          //console.log(users)
          localStorage.removeItem(`userList_${chatid}`);
          localStorage.setItem(`userList_${chatid}`,JSON.stringify(users));
         
          console.log("HALLO")
         
     

          setInitalMessages(res.data);
          scrollToBottom();
        }
      })
      .catch((error) => {
        console.log(error);
      });
  };


// === RESIZE ====

const resizeMe = (img) =>  {
  
  var canvas = document.createElement('canvas');

  var max_width = 50
  var max_height = 50
  var width = img.width;
  var height = img.height;
  console.log(width)
  console.log(height)
  // calculate the width and height, constraining the proportions
  if (width > height) {
    if (width > max_width) {
      //height *= max_width / width;
      height = Math.round(height *= max_width / width);
      width = max_width;
      
    }
  } else {
    if (height > max_height) {
      //width *= max_height / height;
      width = Math.round(width *= max_height / height);
      height = max_height;
      
    }
  }
  
  // resize the canvas and draw the image data into it
  canvas.width = width;
  canvas.height = height;
  var ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0, width, height);
  
  return canvas.toDataURL("image/jpeg",0.7); // get the data from canvas as 70% JPG (can be also PNG, etc.)
  
  // you can get BLOB too by using canvas.toBlob(blob => {});

}



  const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
    const byteCharacters = atob(b64Data);
    const byteArrays = [];
  
    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
      const slice = byteCharacters.slice(offset, offset + sliceSize);
  
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
  
      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }
  
    const blob = new Blob(byteArrays, {type: contentType});
    return blob;
  }

【问题讨论】:

    标签: javascript reactjs async-await blob


    【解决方案1】:

    如果其余代码工作正常,那么我想说您唯一需要更改的是将“oneUser”变量创建放在“image.onload”回调中,因为这是异步操作发生的地方.

    // ...
    
    image.onload = function() {
        var  resized =  resizeMe(image); // resized image url
        // BASE64 zu Blob Url
        resized = resized.split(",");
        resized = resized[1]
        const contentType = 'image/png';
        const b64Data = resized;
        const blob = b64toBlob(b64Data, contentType);
        user_image = URL.createObjectURL(blob);
        console.log(user_image)
    
        // INITIALIZE THE USER HERE
        var oneUser = {
           id: user.user.id_profile,
           username: user.user.username,
           image: user_image,
        };
        users.push(oneUser);
        
        // SAVE THE USERS
        localStorage.removeItem(`userList_${chatid}`);
        localStorage.setItem(`userList_${chatid}`,JSON.stringify(users));
    }
      
    // ...      
    

    由于事件不是基于 Promise 的,因此您不能使用 async-await 语法等待此类操作(除非您为其创建 Promise 包装器,但我认为这是不必要的)。

    【讨论】:

    • 感谢您的评论。我也试过了。问题是代码 sn-p localStorage.setItem('userList_${chatid}',JSON.stringify(users)); 如果我将 user 粘贴到 image.onload 回调中,localStorage 将保存一个空对象。 ://
    • 好的,我没有看到它在那里被使用,在这种情况下,你也可以把这个命令放在回调中!如果另一个命令也要求先保存用户,那么你可以把他们都放在那里。这就是引入异步等待的原因,以避免“回调地狱”。我正在相应地更新我的答案:)
    猜你喜欢
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    相关资源
    最近更新 更多