Saltar al contenido

espera asíncrona en la carga de imágenes

Encontramos el hallazgo a este apuro, o por lo menos eso creemos. Si tienes preguntas coméntalo y sin tardanza

Solución:

Su problema aquí se extiende desde la definición de await

los await El operador se utiliza para esperar un Promise

los Image.prototype.onload la propiedad no es una promesa, ni le estás asignando una. Si quieres devolver el height propiedad después de la carga, en su lugar crearía una Promise

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

Luego usaría lo siguiente para acceder a ese valor

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

o, si dentro de un async función

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

Si bien la solución propuesta funciona perfectamente, quiero poder evitar escribir promesas para cada función asíncrona, así que escribí una función de utilidad genérica solo para este propósito:

en javascript

function onload2promise(obj)
    return new Promise((resolve, reject) => 
        obj.onload = () => resolve(obj);
        obj.onerror = reject;
    );

en mecanografiado (incluidas algunas comprobaciones de tipo genéricas):

interface OnLoadAble 
   onload: any;

function onload2promise(obj: T): Promise 
   return new Promise((resolve, reject) => 
   obj.onload = () => resolve(obj);
   obj.onerror = reject;
 );

En el ejemplo de la pregunta, ahora puedes hacer:

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;

Por supuesto, la llamada en otroarchivo.js también debería ocurrir de forma asíncrona, como se explica en el último bloque de código de la respuesta de Phils

Las respuestas anteriores son correctas, pero quería señalar que ahora hay un HTMLImageElement.decode() método que casi corresponde a un controlador de carga prometido.

Esto tiene las ventajas de no tener que envolverlo usted mismo, manejar imágenes ya cargadas (las respuestas anteriores fallan en este caso) y esperar a que la imagen se decodifique, lo que puede ser bueno en varias situaciones (por ejemplo, si quería usarlo con el Canvas2DContext síncrono.drawImage() método, su secuencia de comandos se bloquearía mientras se realiza esta decodificación).

Así que ahora todo lo que se necesita es

(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 ` );
)();

Comentarios y puntuaciones

Puedes asistir nuestra función ejecutando un comentario o valorándolo te estamos eternamente agradecidos.

¡Haz clic para puntuar esta entrada!
(Votos: 1 Promedio: 1)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *