这是睡眠功能:

    function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}


这是用于实现文本区域内容的功能:

    Luminosidad.prototype.prueba = function(num)
{
    document.getElementById("pruebas").value = num;
}


当我想循环执行时,只能看到最后一个值。
这是代码:

for (var i = 1; i < 8; i++)
    {
        sleep(this.opcion.velocidad);
        this.prueba(i);
    }


在文本区域上,我只能看到“ 7”,即最后一个数字。就像没有正确实现。为什么会发生? (睡眠正常)

最佳答案

为什么会发生?


因为您从未让浏览器有机会显示您正在进行的更新,因为您使UI线程忙于无意义地循环。

从根本上说,忙碌等待永远不是解决任何情况的正确方法。

在这种情况下,您要查找的是一系列setInterval中的setTimeout



function Luminosidad() {}
Luminosidad.prototype.prueba = function(num) {
  document.getElementById("pruebas").value = num;
};
Luminosidad.prototype.loop = function(milliseconds) {
  var i = 1;
  var obj = this;

  setTimeout(next, milliseconds);

  function next() {
    obj.prueba(i++);
    if (i < 8) {
      setTimeout(next, milliseconds);
    }
  }
};
var l = new Luminosidad();
l.loop(500);

<input type="text" id="pruebas">





注意:loop函数将在对pruebas元素进行任何更新之前返回。如果您有需要在所有更新完成后运行的逻辑,则希望让loop接受回调或返回承诺。

由于JavaScript还没有标准形式的Promise(它们是ES6中的东西,所以根本就不远了),这里有一个回调的例子:



// Requires that your browser support ES6 promises!
function Luminosidad() {}
Luminosidad.prototype.prueba = function(num) {
  document.getElementById("pruebas").value = num;
};
Luminosidad.prototype.loop = function(milliseconds, callback) {
  var i = 1;
  var obj = this;

  setTimeout(next, milliseconds);

  function next() {
    obj.prueba(i++);
    if (i < 8) {
      setTimeout(next, milliseconds);
    } else {
      callback();
    }
  }
};
var l = new Luminosidad();
l.loop(500, function() {
  // This runs when everything is done
  document.body.insertAdjacentHTML(
    "beforeend",
    "All done"
  );
});

<input type="text" id="pruebas">





在ES6中,您可以改用诺言:



// Requires that your browser support ES6 promises!
function Luminosidad() {}
Luminosidad.prototype.prueba = function(num) {
  document.getElementById("pruebas").value = num;
};
Luminosidad.prototype.loop = function(milliseconds) {
  var obj = this;
  return new Promise(function(resolve) {
    var i = 1;

    setTimeout(next, milliseconds);

    function next() {
      obj.prueba(i++);
      if (i < 8) {
        setTimeout(next, milliseconds);
      } else {
        resolve();
      }
    }
  });
};
var l = new Luminosidad();
l.loop(500).then(function() {
  // This runs when everything is done
  document.body.insertAdjacentHTML(
    "beforeend",
    "All done"
  );
});

<input type="text" id="pruebas">

09-19 12:50