异步等待图像加载

Rah*_*hul 14 javascript async-await ecmascript-6

Temp.js

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

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)
Run Code Online (Sandbox Code Playgroud)

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

Phi*_*hil 30

你的问题在于...... 的定义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
  })
}
Run Code Online (Sandbox Code Playgroud)

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

tmp.addImageProcess(imageUrl).then(height => {
  console.log(height)
})
Run Code Online (Sandbox Code Playgroud)

或者,如果在一个async功能中

async function logImageHeight(imageUrl) {
  console.log('height', await tmp.addImageProcess(imageUrl))
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@phil,现在我明白了.addImageProcess中有一个小错字. (2认同)

Kai*_*ido 24

以前的答案是正确的,但我想指出现在有一种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 }` );
})();
Run Code Online (Sandbox Code Playgroud)

  • @stor314 和 IE 与人类不兼容。 (18认同)
  • @AkshayKNair 我同意,希望客户能理解这一点 (2认同)

Pin*_*_be 7

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

在JavaScript中

function onload2promise(obj){
    return new Promise((resolve, reject) => {
        obj.onload = () => resolve(obj);
        obj.onerror = reject;
    });
}
Run Code Online (Sandbox Code Playgroud)

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

interface OnLoadAble {
   onload: any;
}
function onload2promise<T extends OnLoadAble>(obj: T): Promise<T> {
   return new Promise((resolve, reject) => {
   obj.onload = () => resolve(obj);
   obj.onerror = reject;
 });
}
Run Code Online (Sandbox Code Playgroud)

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

async function addImageProcess(src){
    let img = new Image();
    let imgpromise = onload2promise(img); // see comment of T S why you should do it this way.
    img.src = src;
    await imgpromise;
    return this.height;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 你的方法有点危险:它在图像加载开始后设置`onload`。请参阅/sf/ask/1025401891/ (2认同)