【问题标题】:JavaScript: Code moves too fast, should I write a Promise?JavaScript:代码运行太快,我应该写一个 Promise 吗?
【发布时间】:2018-01-27 16:23:25
【问题描述】:

我正在尝试使我的网络应用程序对用户更加友好,我希望它在实际被删除之前消失,而不是立即删除一个元素。问题是我的代码运行得太快了。虽然我知道一切正常,但我需要它等待元素“消失”,然后才能真正被删除。这是什么时候使用Promise 还是我应该使用setTimeout() 的一个很好的例子?

代码概览

check if variables exist
if button is clicked change element opacity (transition: opacity 1s;)
then call deletePostPromise()
then remove the element from the dom

如你所见,我什至将我的伪代码写成一个承诺,then.. then..

具体来说,从row.style.opacity = '0';开始

if (displayPostWrapper && submitPostBtn) {
  displayPostWrapper.addEventListener('click', e => {
    if (e.target && e.target.nodeName == 'BUTTON') {
      e.preventDefault();

      const {  parentElement } = e.target;
      const row    = parentElement.parentElement.parentElement;
      const form   = parentElement;
      const postID = parentElement.childNodes[3].value;;

      row.style.opacity = '0';

      deletePostPromise('http://localhost/mouthblog/ajax/delete_post.ajax.php', `id=${postID}`)
        .then(() => {
          row.remove();
        });

      // row.remove();
    } // if
  }); // click event

编辑

JS

const deletePostPromise = (url, postID) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();

    xhr.open('POST', url, true);

    xhr.onload = () => {
      if (xhr.status == 200) {
        console.log('if (xhr.status == 200)');
        resolve();
      } else {
        reject(xhr.statusText);
      }
    };

    xhr.onerror = () => {
      reject(xhr.statusText);
    };

    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    xhr.send(postID);
  });
}

if (displayPostWrapper && submitPostBtn) {
  displayPostWrapper.addEventListener('click', e => {
    if (e.target && e.target.nodeName == 'BUTTON') {
      e.preventDefault();

      const { parentElement } = e.target;
      const row               = parentElement.parentElement.parentElement;
      const form              = parentElement;
      const postID            = parentElement.childNodes[3].value;;

      row.style.opacity = '0';

      deletePostPromise('http://localhost/mouthblog/ajax/delete_post.ajax.php', `id=${postID}`);

      row.addEventListener("transitionend", function(event) {
        // alert('Done!');
        row.remove();
      }, false);
    } // if
  }); // click event

CSS

.row {
      opacity: 1;
      transition: opacity 5s;
    }

【问题讨论】:

  • 在这里使用没有setTimeout 的承诺是毫无意义的。如果要等待 1s,请使用超时。
  • 为什么不立即执行 ajax 请求呢?只是不要在第二个时间过去之前从 DOM 中删除元素。
  • @jfriend00 你的意思只是一个简单的if 声明?
  • @Bergi 我想我不明白,using promises without setTimeout is pointless?我得到了第二部分。
  • 你在问你是否会使用承诺 setTimeout。我的意思是说你会同时使用。

标签: javascript asynchronous promise settimeout


【解决方案1】:

您可以设置一个listener using the transitionend event,它会告诉您何时完成不透明度转换,然后您可以移除该元素。

row.addEventListener("transitionend", function(event) {
  console.log("transition completed, removing row");
  row.remove();
}, false);

您可以在更改触发淡出开始的不透明度之前添加此侦听器。

这是一个简单的工作示例,您可以运行它来查看它的工作情况。

function log(msg) {
    let div = document.createElement("div");
    div.innerHTML = msg;
    document.getElementById("log").appendChild(div);
}

document.getElementById("run").addEventListener("click", function() {
    document.getElementById("test").style.opacity = 0;
});

let test = document.getElementById("test");

test.addEventListener("transitionend", function(e) {
    log(`transitionend for ${e.propertyName}, removing DOM element`)
    test.remove();
});
.fade {
   opacity: 1;
   transition: opacity 2s;
}
<button id="run">
Start Animation
</button>
<div class="fade" id="test">
Some content that will fade out
</div>
<div id="log">

</div>

【讨论】:

  • 可能是我今天学到的最简洁的东西,感谢它。
  • 所以我写了自己的监听器,我认为它可以工作。只是让它消失了,但从未调用过row.remove()。所以我复制/粘贴了你的,现在它被立即再次删除,而不是“消失”。什么给了?
  • @BrandonBenefield - 我必须查看您正在使用的实际代码的整个上下文才能看到需要修复的内容。
  • @BrandonBenefield - 仅供参考,在调试异步操作时切勿使用alert(),因为alert() 会影响时间。使用console.log()输出调试信息,在调试控制台中查看。
  • @BrandonBenefield - 是的,现在看来是关于你的 HTML 和 CSS 以及为什么你没有得到正确的转换事件。您的新问题需要表明这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多