异步等待图像加载

时间:2017-09-25 06:54:55

标签: javascript ecmascript-6 async-await

Temp.js

export default class Temp {
    async addImageProcess(src){
        let img = new Image();
        img.src = src;
        return img.onload = await function(){
          return this.height;
        }
    }
}

anotherfile.js

import Temp from '../../classes/Temp'
let tmp = new Temp()

imageUrl ="https://www.google.co.in/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png"
let image = tmp.addImageProcess(imageUrl);
console.log(image)

以上是我的代码。我有一个图片网址并尝试使用异步等待获取图片的属性,但它不起作用,不了解我错过了什么。

3 个答案:

答案 0 :(得分:22)

此处的问题来自the definition for await ...

  

await运算符用于等待Promise

Image.prototype.onload属性不是承诺,也不是一个承诺。如果您想在加载后返回height属性,我会创建一个Promise ...

addImageProcess(src){
  return new Promise((resolve, reject) => {
    let img = new Image()
    img.onload = () => resolve(img.height)
    img.onerror = reject
    img.src = src
  })
}

然后,您将使用以下内容访问该值

tmp.addImageProcess(imageUrl).then(height => {
  console.log(height)
})

或者,如果在async函数内

async function logImageHeight(imageUrl) {
  console.log('height', await tmp.addImageProcess(imageUrl))
}

答案 1 :(得分:4)

虽然提出的解决方案可以完美地工作,但我希望能够避免为每个异步函数编写Promise,因此我为此目的编写了一个通用实用程序函数:

在javascript中

function onload2promise(obj){
    return new Promise(resolve => {
        obj.onload = () => resolve(obj);
    });
}

在打字稿中(包括一些通用的类型检查):

interface OnLoadAble {
   onload: any;
}
function onload2promise<T extends OnLoadAble>(obj: T): Promise<T> {
   return new Promise(resolve => {
   obj.onload = () => resolve(obj);
 });
}

在问题示例中,您现在可以执行以下操作:

async addImageProcess(src){
    let img = new Image();
    img.src = src;
    await onload2promise(img);
    return this.height();
}

当然,在 anotherfile.js 中的调用也应该仍然异步发生,如Phils answer的最后一个代码块中所述

答案 2 :(得分:3)

以前的答案是正确的,但我想指出的是,现在有一个HTMLImageElement.decode()方法几乎与Promisified onload处理程序相对应。

这样做的优点是不需要自己包装,不需要处理已经加载的图像(以前的回答在这种情况下失败),并且不需要等待图像被实际解码,这在各种情况下都是一件好事(例如,如果您想将其与同步Canvas2DContext。drawImage()方法一起使用,则在完成解码后,脚本将被阻止。)

所以现在只需要

(async () => {
  const img = new Image();
  img.src = "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
  await img.decode();
  // img is ready to use
  console.log( `width: ${ img.width }, height: ${ img.height }` );
})();