代码之家  ›  专栏  ›  技术社区  ›  inyourface3445

更改表单中的值会导致延迟

  •  0
  • inyourface3445  · 技术社区  · 2 年前

    我想将a的值从每秒更改一次,但当我使用此代码时:

    let btn = document.createElement("button");
    function sleep (time) { // number of ms
      return new Promise((resolve) => setTimeout(resolve, time));
    }
    btn.innerHTML = "Save", btn.onclick = function() {
        var value = 0;
        while (true){
          sleep(1000).then(() => {if (value == 1){
            document.getElementById("input").setAttribute('value', '1');
            value += 1;
          } else if (value == 2){
            document.getElementById("input").setAttribute('value', '2');
            value += 1;
          } else if (value == 3){
            document.getElementById("input").setAttribute('value', '3');
            value += 1;
          } else if (value == 4){
            document.getElementById("input").setAttribute('value', '4');
            value += 1;
          } else if (value == 5){
            document.getElementById("input").setAttribute('value', '5');
            value += 1;
          } else if (value == 6){
            document.getElementById("input").setAttribute('value', '6');
            value += 1;
          } else if (value == 7){
            document.getElementById("input").setAttribute('value', '7');
            value += 1;
          } else if (value == 8){
            document.getElementById("input").setAttribute('value', '8');
            value += 1;
          } else if (value == 9){
            document.getElementById("input").setAttribute('value', '9');
            value += 1;
          } else if (value == 0){
            document.getElementById("input").setAttribute('value', '0');
            value = 0;
          }});
        }
    }, document.body.appendChild(btn);
    

    标签完全锁定,我被迫重新加载。我也尝试过使用 document.getElementById("input").value = "value"; ,但这会导致同样的事情发生。有人知道如何解决这个问题吗(表单没有名称)?

    1 回复  |  直到 2 年前
        1
  •  3
  •   Robin Zigmond    2 年前

    问题在于,您有一个经典的“忙循环”,它会在执行Javascript代码时锁定浏览器,而不会让浏览器有机会执行任何其他操作,比如更新UI或响应用户操作。

    你的 while true 循环,没有 break 里面的语句,只是永远运行。每次它运行时,你都会在那里做出承诺——这是 sleep(1000).then(...) ,但这一承诺的决心从未得到遵守的机会。这个 .then 不会在一秒钟后自动发生,不管发生了什么——它只能在浏览器事件循环安排它运行时发生,而在这里它永远不会这样做,因为你有永远不会结束的同步(阻塞)代码,但必须先运行。

    如果你想让效果每秒钟运行一次,就不用麻烦循环了,只要使用 setInterval 而不是 setTimeout .你甚至不想在这里使用承诺,因为承诺只能解决一次问题 设定间隔 持续运行其处理程序。所以你只需要这样的东西:

    btn.onclick = function() {
      var value = 0;
      setInterval(function() {/* what you had in the .then goes here */}, 1000);
    };