Quiero cambiar el valor de a de una vez por segundo, pero cuando uso este código:
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); La pestaña se bloquea por completo y me veo obligado a volver a cargarla. También he intentado usar document.getElementById("input").value = "value"; , pero eso hace que suceda lo mismo. ¿Alguien sabe cómo solucionar esto (el formulario no tiene nombre)?
El problema es que tiene un "bucle ocupado" clásico que bloquea el navegador al ejecutar código Javascript, sin darle al navegador la oportunidad de hacer nada más como actualizar la interfaz de usuario o responder a las acciones del usuario.
Su bucle while true , sin declaración de break dentro, simplemente se ejecuta para siempre. Cada vez que se ejecuta, pones una Promesa allí, el resultado de sleep(1000).then(...) , pero la resolución de esa Promesa nunca tiene la oportunidad de ser observada. El .then no sucede automáticamente después de un segundo, independientemente de lo que esté sucediendo; solo puede suceder cuando el bucle de eventos del navegador lo programa para ejecutarse, lo que nunca puede hacer aquí porque tiene sincronización (bloqueo) código que nunca termina, pero que debe ejecutarse primero.
Si, como parece, desea que el efecto se ejecute cada segundo, no se moleste con un bucle y simplemente use setInterval en lugar de setTimeout . Ni siquiera desea usar Promises aquí, ya que Promises solo puede resolverse una vez mientras setInterval ejecuta su controlador continuamente. Así que todo lo que necesitas es algo como esto:
btn.onclick = function() { var value = 0; setInterval(function() {/* what you had in the .then goes here */}, 1000); };