Reputation: 11
This is the sleep function:
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
This is a function for actualize the textarea content:
Luminosidad.prototype.prueba = function(num)
{
document.getElementById("pruebas").value = num;
}
When i want do it in a loop, i can only see the last value. This is the code:
for (var i = 1; i < 8; i++)
{
sleep(this.opcion.velocidad);
this.prueba(i);
}
On the textarea, i can only see "7", the last number. It is like don't actualize correcly. Why can it happens? (sleep works correctly)
Upvotes: 1
Views: 57
Reputation: 1074018
Why can it happens?
Because you never give the browser a chance to show the updates you're making, because you're keeping the UI thread busy looping pointlessly.
Busy-waits are essentially never the right answer to basically any situation.
In this case, what you're looking for is either setInterval
of a series of setTimeout
s:
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">
Note: The loop
function returns before any updates to the pruebas
element. If you have logic that needs to run after all the updates are complete, you'll want to have loop
either accept a callback or return a promise.
Since JavaScript doesn't have a standard form of promise yet (they're coming in ES6, so not far away at all), here's an example of having a callback:
// 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">
In ES6, you might use a promise instead:
// 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">
Upvotes: 5