8

The following function takes and image from an url, loads it, and returns its width and height:

function getImageData (url) {
  const img = new Image()
  img.addEventListener('load', function () {
    return { width: this.naturalWidth, height: this.naturalHeight }
  })
  img.src = url
}

The problem is, if I do something like this:

ready () {
  console.log(getImageData(this.url))
}

I get undefined because the function runs but the imaged hasn't loaded yet.

How to use await/async to return the value only when the photo has loaded and the width and height is already available?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
alex
  • 7,111
  • 15
  • 50
  • 77

2 Answers2

33

How to use async/await to turn this callback function into a promise?

You don't. As usual, you use the new Promise constructor. There's no syntactic sugar for that.

function loadImage(url) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.addEventListener('load', () => resolve(img));
    img.addEventListener('error', reject); // don't forget this one
    img.src = url;
  });
}

How to use await/async to log the value only when the photo has loaded and the width and height is already available?

You can do

async function getImageData(url) {
  const img = await loadImage(url);
  return { width: img.naturalWidth, height: img.naturalHeight };
}
async function ready() {
  console.log(await getImageData(this.url))
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

This library works pretty well - it allows connection to the child process or simply returns the result asynchronously if desired: https://github.com/expo/spawn-async

James Gentes
  • 7,528
  • 7
  • 44
  • 64