es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿No logro que una promesa de JavaScript espere para agregar o eliminar un elemento? (Parece que solo espera para setTimeout())

Digamos que tengo el siguiente código JavaScript muy simple:

function addPicture(name){
    var src = document.getElementById("mainConsole");
    var img = new Image();

    img.onload=function() {
        img.id=name;
        src.appendChild(img);
    }
    img.src = name;
}

function clearpicture(name){
  var elem = document.getElementById(name);
  elem.remove();
}

Esto parece funcionar bien siempre que estas funciones no estén aisladas en rápida sucesión. Haciendo que el usuario haga clic en un enlace:

<a href="javascript:void(0);" onclick="clearpicture('1.jpg');">test1</a>

remueve la imagen como se espera. Sin embargo, si solo uso este código:

addPicture("1.jpg");
clearpicture("1.jpg");

Obtengo: TypeError: elem is null. ¡Puedo resolver este problema con una promesa!

let p = new Promise(function(resolve, reject) {
    setTimeout(() => resolve(1), 1000); // (*)
    console.log("now");
}).then(function(result) {
    clearpicture("1.jpg");
});

Todo funciona normalmente (después del retraso especificado, por supuesto). Luego, intenté hacer que la promesa esperara en la subrutina addpicture en lugar de setTimeout:

let p = new Promise(function(resolve, reject) {
    addPicture("1.jpg","1",100,0,0);
    resolve(1);
}).then(function(result) {
    clearpicture("1.jpg");
    console.log("picture removed");
});

Obtengo el mismo error null. En mi aplicación real, tengo tiempo para que la imagen se cargue, pero si intento eliminar una serie de imágenes al mismo tiempo:

clearpicture("1.jpg");
clearpicture("2.jpg");
clearpicture("3.jpg");

Nada se elimina, aunque tenga en cuenta que habría algún retraso ya que ambas subrutinas hacen un procesamiento antes de agregar o eliminar algo.

¿Cómo puedo hacer que el código JavaScript espere a que una imagen se cargue por completo o sea eliminada antes de hacer cualquier otra cosa?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para hacer que el código javascript espere a que una imagen se cargue completamente o se elimine antes de hacer cualquier otra cosa, se pueden utilizar promesas en combinación con el evento onload para imágenes.

    Por ejemplo, se puede modificar la función addPicture para que devuelva una promesa que se resuelva cuando la imagen haya terminado de cargar:

    function addPicture(name){
      return new Promise(function(resolve, reject) {
        var src = document.getElementById("mainConsole");
        var img = new Image();
    
        img.onload=function() {
          img.id=name;
          src.appendChild(img);
          resolve();
        }
        img.src = name;
      });
    }
    

    Luego, se puede utilizar la promesa devuelta por addPicture para asegurarse de que la imagen haya terminado de cargar antes de intentar eliminarla:

    addPicture("1.jpg")
      .then(function() {
        return clearpicture("1.jpg");
      })
      .then(function() {
        console.log("imagen eliminada");
      });
    

    De manera similar, se puede modificar la función clearPicture para que devuelva una promesa que se resuelva cuando la imagen haya sido completamente eliminada del DOM:

    function clearpicture(name){
      return new Promise(function(resolve, reject) {
        var elem = document.getElementById(name);
        if(elem) {
          elem.parentNode.removeChild(elem);
          resolve();
        } else {
          reject();
        }
      });
    }
    

    Luego, se pueden utilizar estas promesas para encadenar las llamadas a addPicture y clearPicture, asegurándose de que cada imagen se cargue completamente y luego se elimine antes de pasar a la siguiente:

    addPicture("1.jpg")
      .then(function() {
        return addPicture("2.jpg");
      })
      .then(function() {
        return addPicture("3.jpg");
      })
      .then(function() {
        return clearpicture("1.jpg");
      })
      .then(function() {
        return clearpicture("2.jpg");
      })
      .then(function() {
        return clearpicture("3.jpg");
      })
      .then(function() {
        console.log("todas las imágenes eliminadas");
      });
    

    Esto asegurará que cada imagen se cargue completamente y luego se elimine antes de pasar a la siguiente, resolviendo cada promesa a su vez.

Comments are closed.