while infinito for ejemplos ciclo bucle javascript loops sleep

infinito - ciclo while en javascript



¿Cómo agrego un retraso en un bucle de JavaScript? (23)

Me gustaría agregar un retraso / reposo dentro de un bucle while:

Lo intenté así:

alert(''hi''); for(var start = 1; start < 10; start++) { setTimeout(function () { alert(''hello''); }, 3000); }

Solo el primer escenario es verdadero: después de mostrar la alert(''hi'') , estará esperando 3 segundos, luego se mostrará la alert(''hello'') pero luego la alert(''hello'') se repetirá constantemente.

Lo que me gustaría es que después de que se muestre la alert(''hello'') 3 segundos después de la alert(''hello'') tenga que esperar 3 segundos para la alert(''hello'') la segunda vez alert(''hello'') etc.


Aquí es cómo creé un bucle infinito con un retraso que se rompe en una determinada condición:

// Now continuously check the app status until it''s completed, // failed or times out. The isFinished() will throw exception if // there is a failure. while (true) { let status = await this.api.getStatus(appId); if (isFinished(status)) { break; } else { // Delay before running the next loop iteration: await new Promise(resolve => setTimeout(resolve, 3000)); } }

La clave aquí es crear una nueva Promesa que se resuelva con el tiempo de espera y esperar su resolución.

Obviamente necesitas soporte asíncrono / espera para eso. Trabaja en el nodo 8.


Aquí hay una función que uso para hacer un bucle sobre una matriz:

loopOnArrayWithDelay(YourArray, 1000, 0, function(e, i){ //Do something with item }, function(i){ //Do something once loop has completed }

Lo usas así:

function timer(start) { setTimeout(function () { //The timer alert(''hello''); }, start*3000); //needs the "start*" or else all the timers will run at 3000ms } for(var start = 1; start < 10; start++) { timer(start); }


Creo que necesitas algo como esto:

var TimedQueue = function(defaultDelay){ this.queue = []; this.index = 0; this.defaultDelay = defaultDelay || 3000; }; TimedQueue.prototype = { add: function(fn, delay){ this.queue.push({ fn: fn, delay: delay }); }, run: function(index){ (index || index === 0) && (this.index = index); this.next(); }, next: function(){ var self = this , i = this.index++ , at = this.queue[i] , next = this.queue[this.index] if(!at) return; at.fn(); next && setTimeout(function(){ self.next(); }, next.delay||this.defaultDelay); }, reset: function(){ this.index = 0; } }

Código de prueba:

var now = +new Date(); var x = new TimedQueue(2000); x.add(function(){ console.log(''hey''); console.log(+new Date() - now); }); x.add(function(){ console.log(''ho''); console.log(+new Date() - now); }, 3000); x.add(function(){ console.log(''bye''); console.log(+new Date() - now); }); x.run();

Nota: el uso de alertas detiene la ejecución de javascript hasta que cierre la alerta. Puede ser más código del que solicitó, pero esta es una solución robusta y reutilizable.


Desde ES7 hay una mejor manera de esperar un bucle:

var period = 1000; // ms var endTime = 10000; // ms var counter = 0; var sleepyAlert = setInterval(function(){ alert(''Hello''); if(counter === endTime){ clearInterval(sleepyAlert); } counter += period; }, period);

Referencia: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

Tenga en cuenta que ES7 rara vez se admite hoy en día, por lo que necesita hacer una transferencia con Babel para usarlo en todas partes.

Transpiled


En ES6 (ECMAScript 2015) puede iterar con retraso con generator e intervalo.

Los generadores, una nueva característica de ECMAScript 6, son funciones que se pueden pausar y reanudar. Llamar a genFunc no lo ejecuta. En su lugar, devuelve un llamado objeto generador que nos permite controlar la ejecución de genFunc. genFunc () se suspende inicialmente al principio de su cuerpo. El método genObj.next () continúa la ejecución de genFunc, hasta el próximo rendimiento. (Explorando ES6)


Ejemplo de código:

let arr = [1, 2, 3, ''b'']; let genObj = genFunc(); let val = genObj.next(); console.log(val.value); let interval = setInterval(() => { val = genObj.next(); if (val.done) { clearInterval(interval); } else { console.log(val.value); } }, 1000); function* genFunc() { for(let item of arr) { yield item; } }

Entonces, si está utilizando ES6, esa es la forma más elegante de lograr un bucle con retraso (en mi opinión).


Este script funciona para la mayoría de las cosas

var timer, i = 10; function myLoop () { // create a loop function timer = setTimeout(function () { document.getElementById("demo").innerHTML = i; i--; if (i >= 0) { myLoop(); } else { clearTimeout(timer); // clear timeout document.getElementById("demo").innerHTML = "DOARRRR .."; } }, 1000); } myLoop();


Esto funcionara

function timer(ms) { return new Promise(res => setTimeout(res, ms)); } async function load () { for (var i = 0; i < 3; i++) { console.log(i); await timer(3000); } } load();

Pruebe este violín: https://jsfiddle.net/wgdx8zqq/


Implementación simple de mostrar un fragmento de texto cada dos segundos mientras el bucle se esté ejecutando.

function loopOnArrayWithDelay(theArray, delayAmount, i, theFunction, onComplete){ if (i < theArray.length && typeof delayAmount == ''number''){ console.log("i "+i); theFunction(theArray[i], i); setTimeout(function(){ loopOnArrayWithDelay(theArray, delayAmount, (i+1), theFunction, onComplete)}, delayAmount); }else{ onComplete(i); } }


Intenta algo como esto:

var i = 0, howManyTimes = 10; function f() { alert( "hi" ); i++; if( i < howManyTimes ){ setTimeout( f, 3000 ); } } f();


La función setTimeout() no es de bloqueo y regresará inmediatamente. Por lo tanto, su bucle se repetirá muy rápidamente e iniciará el tiempo de espera de 3 segundos, uno tras otro, en rápida sucesión. Es por eso que sus primeras alertas aparecen después de 3 segundos, y todo lo demás sigue en sucesión sin demora.

Es posible que desee utilizar algo como esto en su lugar:

var i = 1; // set your counter to 1 function myLoop () { // create a loop function setTimeout(function () { // call a 3s setTimeout when the loop is called alert(''hello''); // your code here i++; // increment the counter if (i < 10) { // if the counter < 10, call the loop function myLoop(); // .. again which will trigger another } // .. setTimeout() }, 3000) } myLoop(); // start the loop

También puedes mejorarlo, usando una función de invocación automática, pasando el número de iteraciones como un argumento:

(function myLoop (i) { setTimeout(function () { alert(''hello''); // your code here if (--i) myLoop(i); // decrement i and call myLoop again if i > 0 }, 3000) })(10); // pass the number of iterations as an argument


Lo hago con Promise.delay y recursión de Bluebird.

function myLoop(i) { return Promise.delay(1000) .then(function() { if (i > 0) { alert(''hello''); return myLoop(i -= 1); } }); } myLoop(3);

<script src="//cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.4/bluebird.min.js"></script>


Otra forma es multiplicar el tiempo de espera, pero tenga en cuenta que esto no es como dormir . El código después de que el bucle se ejecute inmediatamente, solo se aplaza la ejecución de la función de devolución de llamada.

for (var start = 1; start < 10; start++) setTimeout(function () { alert(''hello''); }, 3000 * start);

El primer tiempo de espera se establecerá en 3000 * 1 , el segundo en 3000 * 2 y así sucesivamente.


Probablemente usaría setInteval . Me gusta esto,

for (var i = 0; i < 10; i++) { (function(i) { setTimeout(function() { console.log(i); }, 100 * i); })(i); }


Prueba esto

//the code will execute in 1 3 5 7 9 seconds later function exec(){ for(var i=0;i<5;i++){ setTimeout(function(){ console.log(new Date()); //It''s you code },(i+i+1)*1000); } }


Prueba esto...

//the code will execute in 1 3 5 7 9 seconds later function exec(){ for(var i=0;i<5;i++){ setTimeout(function(){ console.log(new Date()); //It''s you code },(i+i+1)*1000); } }


Puede utilizar el operador de intervalo RxJS. El intervalo emite un entero cada x cantidad de segundos, y tomar es especificar el número de veces que tiene que emitir números

Rx.Observable .interval(1000) .take(10) .subscribe((x) => console.log(x))

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.lite.min.js"></script>


Si usa ES6, puede usar let para lograr esto:

for (let i=1; i<10; i++) { setTimeout( function timer(){ alert("hello world"); }, i*3000 ); }

Lo que let hacer es declarar i para cada iteración , no el bucle. De esta manera, lo que se pasa a setTimeout es exactamente lo que queremos.


Solo pensé que también pondría mis dos centavos aquí. Esta función ejecuta un bucle iterativo con un retraso. Ver este jsfiddle . La función es la siguiente:

function timeout(range, time, callback){ var i = range[0]; callback(i); Loop(); function Loop(){ setTimeout(function(){ i++; if (i<range[1]){ callback(i); Loop(); } }, time*1000) } }

Por ejemplo:

//This function prints the loop number every second timeout([0, 5], 1, function(i){ console.log(i); });

Sería equivalente a:

//This function prints the loop number instantly for (var i = 0; i<5; i++){ console.log(i); }


para uso común "olvide los bucles normales" y use esta combinación de "setInterval" incluye "setTimeOut" s: así (de mis tareas reales).

function iAsk(lvl){ var i=0; var intr =setInterval(function(){ // start the loop i++; // increment it if(i>lvl){ // check if the end round reached. clearInterval(intr); return; } setTimeout(function(){ $(".imag").prop("src",pPng); // do first bla bla bla after 50 millisecond },50); setTimeout(function(){ // do another bla bla bla after 100 millisecond. seq[i-1]=(Math.ceil(Math.random()*4)).toString(); $("#hh").after(''<br>''+i + '' : rand= ''+(Math.ceil(Math.random()*4)).toString()+'' > ''+seq[i-1]); $("#d"+seq[i-1]).prop("src",pGif); var d =document.getElementById(''aud''); d.play(); },100); setTimeout(function(){ // keep adding bla bla bla till you done :) $("#d"+seq[i-1]).prop("src",pPng); },900); },1000); // loop waiting time must be >= 900 (biggest timeOut for inside actions) }

PD: Comprenda que el comportamiento real de (setTimeOut): todos comenzarán al mismo tiempo "los tres bla bla bla comenzarán a contar en el mismo momento", así que haga un tiempo de espera diferente para organizar la ejecución.

PS 2: el ejemplo para el ciclo de temporización, pero para los ciclos de reacción se pueden usar eventos, prometer async await ..


<!DOCTYPE html> <html> <body> <button onclick="myFunction()">Try it</button> <p id="demo"></p> <script> function myFunction() { for(var i=0; i<5; i++) { var sno = i+1; (function myLoop (i) { setTimeout(function () { alert(i); // Do your function here }, 1000*i); })(sno); } } </script> </body> </html>


<p id="demo">count</p>

var icount=0; for (let i in items) { icount=icount+1000; new beginCount(items[i],icount); } function beginCount(item,icount){ setTimeout(function () { new actualFunction(item,icount); }, icount); } function actualFunction(item,icount){ //...runs ever 1 second console.log(icount); }


var startIndex = 0; var data = [1, 2, 3]; var timeout = 1000; function functionToRun(i, length) { alert(data[i]); } (function forWithDelay(i, length, fn, delay) { setTimeout(function() { fn(i, length); i++; if (i < length) { forWithDelay(i, length, fn, delay); } }, delay); })(startIndex, data.length, functionToRun, timeout);

Una versión modificada de la respuesta de Daniel Vassallo, con variables extraídas en parámetros para hacer la función más reutilizable:

Primero definamos algunas variables esenciales:

var startIndex = 0; var data = [1, 2, 3]; var timeout = 3000;

A continuación debe definir la función que desea ejecutar. Esto se pasará i, el índice actual del bucle y la longitud del bucle, en caso de que lo necesite:

function functionToRun(i, length) { alert(data[i]); }

Versión autoejecutable

(function forWithDelay(i, length, fn, delay) { setTimeout(function () { fn(i, length); i++; if (i < length) { forWithDelay(i, length, fn, delay); } }, delay); })(startIndex, data.length, functionToRun, timeout);

Versión funcional

function forWithDelay(i, length, fn, delay) { setTimeout(function () { fn(i, length); i++; if (i < length) { forWithDelay(i, length, fn, delay); } }, delay); } forWithDelay(startIndex, data.length, functionToRun, timeout); // Lets run it


/* Use Recursive and setTimeout call below function will run loop loopFunctionNeedCheck until conditionCheckAfterRunFn = true, if conditionCheckAfterRunFn == false : delay reRunAfterMs miliseconds and continue loop tested code, thanks */ function functionRepeatUntilConditionTrue(reRunAfterMs, conditionCheckAfterRunFn, loopFunctionNeedCheck) { loopFunctionNeedCheck(); var result = conditionCheckAfterRunFn(); //check after run if (!result) { setTimeout(function () { functionRepeatUntilConditionTrue(reRunAfterMs, conditionCheckAfterRunFn, loopFunctionNeedCheck) }, reRunAfterMs); } else console.log("completed, thanks"); //if you need call a function after completed add code call callback in here } //passing-parameters-to-a-callback-function // From Prototype.js if (!Function.prototype.bind) { // check if native implementation available Function.prototype.bind = function () { var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift(); return function () { return fn.apply(object, args.concat(Array.prototype.slice.call(arguments))); }; }; } //test code: var result = 0; console.log("---> init result is " + result); var functionNeedRun = function (step) { result+=step; console.log("current result is " + result); } var checkResultFunction = function () { return result==100; } //call this function will run loop functionNeedRun and delay 500 miliseconds until result=100 functionRepeatUntilConditionTrue(500, checkResultFunction , functionNeedRun.bind(null, 5)); //result log from console: /* ---> init result is 0 current result is 5 undefined current result is 10 current result is 15 current result is 20 current result is 25 current result is 30 current result is 35 current result is 40 current result is 45 current result is 50 current result is 55 current result is 60 current result is 65 current result is 70 current result is 75 current result is 80 current result is 85 current result is 90 current result is 95 current result is 100 completed, thanks */