I want to add a delay / sleep in the while loop:
I've tried this:
alert('hi'); for(var start = 1; start < 10; start++) { setTimeout(function () { alert('hello'); }, 3000); }
Only the first scenario is real: after display, alert('hi ') will wait for 3 seconds, then alert('hello') will be displayed, but then alert('hello ') will be repeated.
What I want is that after the alert('hi ') is displayed for 3 seconds, it needs to wait for 3 seconds for the alert('hello') to appear for the second time, and so on.
#1 building
I might use setinterval. Like this,
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);
#2 building
/* 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 */
#3 building
I do this using Promise.delay and recursion from 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>
#4 building
This is my function for traversing arrays:
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); } }
You can use it like this:
loopOnArrayWithDelay(YourArray, 1000, 0, function(e, i){ //Do something with item }, function(i){ //Do something once loop has completed }
#5 building
In ES6 (ECMAScript 2015), you can use the generator And interval to delay iteration.
Generator is a new feature of ECMAScript 6 that can be paused and resumed. Calling genFunc does not execute it. Instead, it returns a so-called generator object that allows us to control the execution of genFunc. genFunc () initially pauses at the beginning of its body. Method genObj.next() continues to execute genFunc until the next yield. (explore ES6)
Code example:
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; } }
So if you're using ES6, that's the most elegant way to implement delay loops (I think).