如何利用async、await来改进函数?

网上找了一段压缩图片的代码,我把它放到单独的helper.js文件里面,但是由于业务逻辑比较负责,所以不希望用原来的回调来实现,因此希望改进为通过asyncawait这种形式来避免回调的问题,该怎么改进呢?谢谢!
代码如下:

export function compress(fileObj, callback) {
  try {
    const image = new Image();
    image.src = URL.createObjectURL(fileObj);
    image.onload = function() {
      const that = this; 
      let w = that.width;
      let h = that.height;
      const scale = w / h;
      w = fileObj.width || w;
      h = fileObj.height || w / scale;
      let quality = 0.7; 
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");
      const anw = document.createAttribute("width");
      anw.nodeValue = w;
      const anh = document.createAttribute("height");
      anh.nodeValue = h;
      canvas.setAttributeNode(anw);
      canvas.setAttributeNode(anh);
      ctx.drawImage(that, 0, 0, w, h); 
      if (fileObj.quality && fileObj.quality <= 1 && fileObj.quality > 0) {
        quality = fileObj.quality;
      } 
      const data = canvas.toDataURL("image/jpeg", quality); 
      const newFile = convertBase64UrlToBlob(data);
      callback(newFile);//不希望通过此种方式实现
    };
  } catch (e) {
    console.log("error!");
  }
}
function convertBase64UrlToBlob(urlData) {
  const bytes = window.atob(urlData.split(",")[1]); 
  const ab = new ArrayBuffer(bytes.length);
  const ia = new Uint8Array(ab);
  for (let i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i);
  }
  return new Blob([ia], { type: "image/png" });
}

调用的时候,希望可以:

let compedFile = await compress(fileObj);

//上面代码同步执行完成,再执行下面业务逻辑……
阅读 2.5k
2 个回答

大致思路,先让compress返回Promise对象,然后声明为async,

export async function compress(fileObj){
    return new Promise(
        (resolve, reject)=>{
            ....
            const newFile = convertBase64UrlToBlob(data);
            resolve(newFile);
            ....
            catch (e) {
                console.log("error!");
                reject(e);
              }
            
        }
    );
}

@scherman 感觉这么做有一定的局限性。

假设我封装的compress函数返回Promise对象,那么我调用的地方(async函数里面),必须把其他的业务代码写在该函数里面,如下(vue伪代码):

async comp(file) {
    
    let fileObj = file
    if(true){
        fileObj = await compress(file).then(res => {
            return res
        })
    }

    //业务代码
    //this.$axios.post()

},
uploadFileMethod (param) {
    this.comp(param.file)
},

也就是说,业务代码部分必须写到comp函数里面,而不能写到uploadFileMethodthis.comp(param.file)行后面,也就是说把uploadFileMethod里面的整块代码都打包出去了,但是如果我只希望把压缩(comp部分出去业务代码块)部分代码抽到一个单独的函数里面该怎么写呢?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题