Promise方法如何转为同步执行?

想通过Compressorjs来压缩图片上传,于是写了一个压缩方法,基于Promise:

压缩图片方法:

export function comImg(file) {
  return new Promise((resolve, reject) => {
    new Compressor(file, {
      quality: 0.6,
      success(result) {
          resolve(result);
      },
      error(err) {
          reject()
      },
    });
  });
}

包装Promise方法

async function syncWrapper() {
    try {
        const result = await comImg();
        console.log('000000000');
        return result;
    } catch (error) {
        console.error(error);
    }
}

使用:

handleClick(file) {
    let result = this.comp(file);
    console.log('1111111');
},

我希望先输出000000000,再输出1111111,但结果确实相反的,该如何改进呢?

阅读 852
avatarAI BotBETA

由于JavaScript是单线程的,异步代码无法真正同步化,但可以通过async/await模拟同步执行顺序。你的问题出在handleClick中没有正确使用await。需要改成这样:

// 正确调用方式
async handleClick(file) {  // 方法本身要声明为async
    let result = await this.comp(file); // 这里必须加await
    console.log('1111111');
}

// 需要补充异常捕获的话可以这样写:
async handleClick(file) {
    try {
        let result = await this.comp(file);
        console.log('1111111');
    } catch (error) {
        console.error('压缩失败', error);
    }
}

原因解析:

  1. await关键字会暂停当前函数的执行,直到Promise被resolve
  2. 调用异步函数的方法本身也必须用async/await处理
  3. 你原来漏掉了handleClick方法中的await,导致异步操作未等待就直接执行了后续代码

注意事项:

  • 如果handleClick是事件回调(如点击事件),某些环境可能无法直接使用async函数,这时需要在调用处补充.catch()
  • 同步代码写法会阻塞UI,不建议用于耗时操作,但图片压缩这种场景可以接受
1 个回答
✓ 已被采纳

可以用async,await转为同步

export function comImg(file) {
  return new Promise((resolve, reject) => {
    new Compressor(file, {
      quality: 0.6,
      success(result) {
          resolve(result);
      },
      error(err) {
          reject()
      },
    });
  });
}
async handleClick(file) {
    let result = await this.comp(file);
    console.log('1111111');
},
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题