I would like to create a pause inside a while loop so that I can create n animations that each appear 3 seconds after the other.
I've tried the following, but it doesn't work. Would love to have someone show me what I'm doing wrong.
i=0;
while (i < n) {
someanimation();
setTimeout(function(){
i++;
}, 3000);
};
setTimeout does not pause; it asks Javascript to run some other code later.
Googling for "setTimeout loop" tells you exactly what you need to know. If you look around a little bit, it even mentions setInterval. The difference: using setTimeout to loop will wait 3 seconds in between loops, whereas setInterval will make it take 3 seconds total for the loop (including however much time the animation takes, as long as it's less than 3 seconds :) ). Also, setInterval constructs an infinite loop that you'll have to break out of after the desired number of times; setTimeout requires you to construct the loop yourself.
i = 0;
// setTimeout approach
function animation_loop() {
someAnimation();
setTimeout(function() {
i++;
if (i < n) {
animation_loop();
}
}, 3000);
};
animation_loop();
// setInterval approach
i = 0;
someAnimation();
iid = setInterval(function() {
i++;
if (i < n) {
someAnimation();
} else {
clearInterval(iid);
}
}, 3000);
setTimeout is a little trickier than that because it doesn't block (i.e. it doesn't finish waiting on the timeout before continuing with the program).
What you want is closer to this:
var i = 0;
function nextFrame() {
if(i < n) {
someanimation();
i++;
// Continue the loop in 3s
setTimeout(nextFrame, 3000);
}
}
// Start the loop
setTimeout(nextFrame, 0);
It may also be worth your while to read up on setInterval as a possible alternative.
Well, thanks to ES6-7 with Promises we can now make a pause and make it look nice at the same time!
var id = 0;
async function do() {
while(true) {
await pause(id);
//will happen only after pause is done
id++;
}
}
function pause(id) {
return new Promise(resolve => setTimeout(() => {
console.log(`pause ${id} is over`);
resolve();
}, 1500));
}
do();
One of the way of doing it is to use RxJS. Please take a look at working example here
Rx.Observable
.interval(1000)
.take(10)
.subscribe((x) => console.log(x))
create a function like:
function sleep_until (seconds) {
var max_sec = new Date().getTime();
while (new Date() < max_sec + seconds * 1000) {}
return true;
}
and then change your code to
i=0;
while (i < n) {
someanimation();
sleep_until(3);
do_someotheranimation();
};
You are not very specific about what you want to do, but I'd say the main problem is that you call someanimation() without a delay. So maybe this solves it for you:
for (var i = 0; i < n; i++) {
setTimeout(someanimation, 3000 * i);
};
Note the missing () after someanimation as it is the callback for setTimeout().
function myFunction() {
var x;
for(var i=0;i<10;i++){
if (confirm("Press a button!") == true) {
x = "You pressed OK!";
} else {
x = "You pressed Cancel!";
}
document.getElementById("demo").innerHTML = x;
}
}``
Related
I have created the setTimeout which has a callback named run, Inside the run I have called a console.log(i) to print the value of I with i++ and once it reaches to 50, I want to clear the setTimeout with clearTimeout, I am calling setTimeout again with run making it recursive, but it doesn't work.
can somebody help me understand the concept better?
let i = 1;
var abc = setTimeout(function run(){
console.log(i);
if(i==50){
abc1();
}
i++;
setTimeout(run,100);
},100);
function abc1(){
clearTimeout(abc);
}
When you call setTimeout you get the ID of the timer returned. It's exactly what you've done here:
var abc = setTimeout(function run(){
However, that ID is valid only until the delayed function executes. Once it does, it's ineffective. When you call setTimeout(run,100); you will get a new ID for the timer. You need to capture that again, otherwise the ID gets lost and you have no way to stop it.
There is a final consideration - with your current code even if you were to correctly capture the ID calling abc = setTimeout(run, 100); that would still not stop the counter because it will attempt to stop the function that is running right now (which does nothing), instead of cancelling the execution of the next one:
let i = 1;
var abc = setTimeout(function run() {
console.log(i);
if (i == 50) {
abc1(); //this will clear the *current* timer
}
i++;
abc = setTimeout(run, 100); //this will set the *new* ID
}, 100);
function abc1() {
clearTimeout(abc);
}
In order to stop the execution you have two options. If you want to use your initial idea, you need to cancel the future execution after it is scheduled
let i = 1;
var abc = setTimeout(function run() {
console.log(i);
abc = setTimeout(run, 100); //this will set the *new* ID
if (i == 50) {
abc1(); //this will clear the *new* timer now
}
i++;
}, 100);
function abc1() {
clearTimeout(abc);
}
Alternatively, you can do it without using timer handles at all and just use the if condition to determine if you want to schedule another execution or not:
let i = 1;
setTimeout(function run() {
console.log(i);
if (i != 50) { //until 50 is reached
abc = setTimeout(run, 100); //schedule a new execution
}
i++;
}, 100);
The problem is the order of your operations.
if(i==50){
abc1();
}
If i reaches 50, the function abc1() will be called - which clears the interval.
i++;
setTimeout(run,100);
here you're restarting the interval.
You need to wrap it inside an else block.
let i = 1;
var abc = setTimeout(function run() {
console.log(i);
if (i == 50) {
abc1();
} else {
i++;
setTimeout(run, 100);
}
}, 100);
function abc1() {
clearTimeout(abc);
}
let i = 1;
var abc = setTimeout(function run(){
console.log(i);
if(i<50){
setTimeout(run,100);
}
i++;
},100);
You should run timeout only if timer not run out.
The setTimeout() inside run() in not assigned to any variable so it can't be cleared in any manner.
I suppose what you want is to overwrite abc so you must replace:
setTimeout(run,100);
by
abc = setTimeout(run,100);
Since var abc is only set once, at the first timeout, you are clearing only the very first Timeout, which very likely is already complete.
SetTimeout returns a numeric value, which is an ID to refer to that task. When you call clearTimeout, you must inform the ID of the timeout you want to clear, and now you are informing the ID for the very first timeout, which is already finished, thus can't be cleared.
If you wish to clear the last timeout, maybe you would like to always update abc with the IDs for each timeout, like this:
abc = setTimeout(run,100);
This is a weird way of doing a timed loop but you just need to clear (actually not in this case but I like to do it anyway as it is a good practice to release resources once you don't use them anymore) the timeouts (done by keeping track of abc handle) before creating new ones and return after clear on the given condition:
let i = 1;
let abc = setTimeout(
function run(){
console.log(i);
if(i==50){
abc1();
return;
}
abc1();
i++;
abc = setTimeout(run,100);
},
100
);
function abc1(){
clearTimeout(abc);
}
you need to add return after you call abc1 function. you clear timeout, but then code still running and call setTimeout(run,100) again.
let i = 1;
var abc = setTimeout(function run(){
console.log(i);
if(i==50){
abc1();
return;
}
i++;
setTimeout(run,100);
},100);
function abc1(){
clearTimeout(abc);
}
I am trying to loop through an array, but want to output each value of the array with a delay. This is what my current understanding is on how it should work:
EDIT
Requested JS Fiddle: http://jsfiddle.net/d3whkjww/
loopThroughSplittedText: function(splittedText) {
for (var i = 0; i < splittedText.length; i++) {
// for each iteration console.log a word
// and make a pause after it
setTimeout(
console.log(splittedText[i]),
1000
);
};
},
Yet, it does not work, and I believe it might be, because the arguments in the "for" loop have to be inside the setTimeout function. Yet I don't know how to make it work.
All I get is every value of the array at once, but I want them appear with a delay. How do I do that?
var splittedText = ["Hello", "World", "How", "Are", "You", "Today"];
function loopThroughSplittedText(splittedText) {
for (var i = 0; i < splittedText.length; i++) {
// for each iteration console.log a word
// and make a pause after it
(function (i) {
setTimeout(function () {
document.getElementById('text').innerHTML += splittedText[i];
console.log(splittedText[i]);
}, 1000 * i);
})(i);
};
}
loopThroughSplittedText(splittedText);
Fiddle Demo
Chances are you're going to want to use a recursive function instead of a for loop here. However, I'll explain both ways just in case you (or someone else reading this) has your heart set on doing this with a loop.
For a recursive function, the general idea is that you'll want to call the function once, then let it call itself repeatedly until it's finished doing what you want it to do. In terms of code, it will could look something a bit like this:
loopThroughSplittedText: function(splittedText) {
// Create our counter; delayedOutput will use this to
// track how far along in our string we are currently at
var locationInString = 0;
function delayedOutput() {
// Output the next letter in our string
console.log(splittedText[locationInString]);
// Increment our counter so that on the next call we are on the next letter
locationInString++;
// Only perform setTimeout if we still have text left to output
if (locationInString < splittedText.length) {
// Functions can reference themselves using their own name
setTimeout(delayedOutput, 1000);
}
}
// Call our function once to get things started
delayedOutput();
},
Alternatively, if you really prefer using a loop, you can still do it, but there's a fair bit of fiddling that has to be done to accomplish this.
First, you're going to need to place console.log within its own function. This is because when you place console.log(something), you're not actually passing it, but calling it right then and there, which is not what you want; by calling it, it spits out the text to the console right away rather than waiting until later. Tucking it away in its own function allows it to be passed to setTimeout so it can be called later on.
Second, you're going to have to wrap that function in yet another function to ensure that it's given the correct value of i when it fires. The reason is effectively this: Your intention is to tell the function "when you're ready, use what i was when I set you up." However, what you're doing right now is effectively saying "when you're ready, look at i". Because the function doesn't check what i is until it's ready to fire, it won't know its value until long after you have performed the loop, meaning i will be a number much higher than you want!
As a bit of a sub-point to the above, you'll want to call that function immediately. This is known as an immediately invoked function expression. If you're not familiar with them, they're certainly worth looking up. Their uses are a bit unusual, but they're a powerful tool in the right spot.
Finally, because you're setting up everything right here and now, you want to make sure the timeout for each function is a second apart; as it stands now, you're saying "do all of these one second from now", when your intention is "do all of these one second apart, starting one second from now". This fix is relatively easy; all you need to do is multiply your timeout by i so that you set up the first to go 1 second from now, the second to go 2 seconds from now, and so on.
All of that combined gives you code that looks something like this:
loopThroughSplittedText: function(splittedText) {
for (var i = 0; i < splittedText.length; i++) {
setTimeout(
(function(locationInString) {
return function() {
console.log(splittedText[locationInString]);
};
}(i)),
(1000*i)
);
}
},
As for which solution is better, I would probably recommend the recursive function. The recursive version will only create one function that calls itself for every string you pass it, whereas the for loop version will create one function for every character in the string, which could get out of hand very quickly. Function creation (and object creation in general) can get expensive in JavaScript when you're working on larger projects, so it's generally best to favor solutions that avoid creating massive amounts of functions when possible.
But still, for sake of explanation, I wouldn't want to leave you without the for loop version; the knowledge could come in handy in other places. :)
A recursive function call would do the job:
var a = [
1,2,3,4,5,6,7,8,9,10
];
function log(i){
console.log(a[i]);
if (i<a.length){
setTimeout(function(){
i++;
log(i);
},1000);
}
}
log(0);
http://jsfiddle.net/Curt/rjve4whe/1/
In my example, it will show you how to loop through an array contentiously until you stop. This is to just give you an idea on how you can do the delay. Also it shows you when the value actually got displayed.
I would say that you could actually create a nice utility from this timer, and use it for multiple purposes and with the utility it'll stop you from repeating large chunks of code.
JavaScript Loop example:
var body = document.body;
var splittedText = ["Hello", "World", "How", "Are", "You", "Today"];
loopThroughArray(splittedText, function (arrayElement, loopTime) {
body.innerHTML += arrayElement+ ": " + loopTime+ "<br/>";
}, 1000);
function loopThroughArray(array, callback, interval) {
var newLoopTimer = new LoopTimer(function (time) {
var element = array.shift();
callback(element, time - start);
array.push(element);
}, interval);
var start = newLoopTimer.start();
};
// Timer
function LoopTimer(render, interval) {
var timeout;
var lastTime;
this.start = startLoop;
this.stop = stopLoop;
// Start Loop
function startLoop() {
timeout = setTimeout(createLoop, 0);
lastTime = Date.now();
return lastTime;
}
// Stop Loop
function stopLoop() {
clearTimeout(timeout);
return lastTime;
}
// The actual loop
function createLoop() {
var thisTime = Date.now();
var loopTime = thisTime - lastTime;
var delay = Math.max(interval - loopTime, 0);
timeout = setTimeout(createLoop, delay);
lastTime = thisTime + delay;
render(thisTime);
}
}
Ok, as It is not an exact duplicate, you need to increate the delay in the loop, also escape from the closure variable in a loop issue
loopThroughSplittedText: function (splittedText) {
splittedText.forEach(function (text, i) {
setTimeout(function () {
console.log(text);
}, i * 1000)
})
}
var obj = {
loopThroughSplittedText: function(splittedText) {
splittedText.forEach(function(text, i) {
setTimeout(function() {
document.getElementById('x').innerHTML += text
}, i * 1000)
})
}
}
obj.loopThroughSplittedText('abcde'.split(''))
<div id="x"></div>
One problem with your code is that i is common to all the callbacks. So the first callback is told "output the entry at index i", however by the time it gets to execute the initial loop is finished so i is now at the end of the text.
One way to achieve what you're looking for is to not use a for loop, but to have a function which (1) prints a character, (2) updates the counter/position, and (3) schedules the next character if needed:
loopThroughSplitText: function (text) {
var i = 0;
function printEntry() {
console.log(text[i]);
i++; // Increment the position
if (i < text.length) { // If there are more chars, schedule another
setTimeout(printEntry, 1000);
}
}
printEntry(); // Print the first entry/char
}
solution using closure
https://jsfiddle.net/x3azn/pan2oc9y/4/
function loopThroughSplittedText(splittedText) {
var splittedText = ["Hello", "World", "How", "Are", "You", "Today"];
for (var i = 0; i < splittedText.length; i++) {
// for each iteration console.log a word
// and make a pause after it
(function(_i) {
setTimeout(function() {
window.document.getElementById('text').innerHTML = splittedText[_i];
console.log(splittedText[_i]);
}, 1000)
}(i));
}
}
loopThroughSplittedText()
One more solution, with a setInterval:
var i = 0;
var intv = setInterval(function() {
if (i >= splittedText.length) {
clearInterval(intv);
} else {
console.log(splittedText[i]);
++i;
}
}, 1000);
There are a couple of problems here
setTimeout should take a function, not the result of calling a function
setTimeout returns immediately, so all the actions in your loop will be started at roughly the same moment, and all wait 1000ms before execting (notwithstanding the comment above however, which means they're all executed at the same moment).
The value of i will all be equal to splittedText.length for each iteration due to not wrapping your loop control variable in a closure.
What you need to do, is wait until the setTimeout instructions are executed before moving on to the next iteration of the loop.
For example:
var splittedText = ["Hello", "World", "How", "Are", "You", "Today"];
function loopThroughSplittedText(splittedText) {
displayValue(splittedText,0);
}
function displayValue(arr, i){
if(i<arr.length){
setTimeout(function(){
document.getElementById('text').innerHTML = arr[i];
console.log(arr[i])
displayValue(arr,i+1);
},1000)
}
}
loopThroughSplittedText(splittedText)
Live example: http://jsfiddle.net/d3whkjww/1/
This will also work
function loopThroughSplittedText(splittedText) {
for (var i=0; i < splittedText.length;i++) {
(function(ind, text) {
setTimeout(function(){console.log(text);}, 1000 + (1000 * ind));
})(i, splittedText[i]);
}
}
Another sample:
var split = 'Lorem ipsum dolor'.split(' ');
var loop = function() {
console.log(split[0]);
split = split.slice(1);
if (split.length > 0) {
setTimeout(function() {
loop();
}, 1000);
}
}
loop();
Bringing out an alternative solution to the problem, which is making use of the third argument to setTimeout which is only supported in newer browsers:
(function (splittedText) {
for (var i = 0; i < splittedText.length; i++) {
setTimeout(
function(val) { console.log(val); },
i * 1000,
splittedText[i]
);
}
})(["Hello", "world", "!"]);
API documentation can be seen here (note the optional params).
You can achieve by 3 ways
1. closure
2. Recursive
3. variable declaration using let
var data = ['a', 'b', 'c', 'd'];
closure:
for(i=0; i<=data.length; i++) {
(function(x) {
setTimeout(() => {
console.log(x);
}, 1000)
})(data[i]);
}
let variable declaration
for(const ind of data) {
let local = ind;
setTimeout(() => {
console.log(local);
}, 1000)
}
I have this code:
for (i = 0; i < 3; i++) {
var interval = setInterval(function(){
alert(i);
}, 2000);
}
What I would like to achieve is to have an alert every 2 sec displaying first 0, then 1 and lastly 2.
Instead I have to wait for quite long before I have 3 alerts all displaying the number 3. Where is my code wrong?
Well, there is (yet again) more than one solution to this problem. But, lets first talk why your code doesn't work properly.
Your code:
for (i = 0; i < 3; i++) {
var interval = setInterval(function(){
alert(i);
}, 2000);
}
..basically means that it will assign three setInterval calls to be executed after 2 seconds as fast as the for loop is placing them to the queue. So basically, all your calls runs really fast after 2 seconds, only few milliseconds or less between them. Moreover, setInterval means that it will be called as long as clearInterval is called to the variable it is assigned with. In other words, your code never stops executing the alert, because you are never calling clearInterval. Finally, your alert(i) will always display value of 3, because it is the last value of i when execution moves away from the for loop.
To improve your code, you could remove the for loop entirely and just let setInterval run as long as the value of i is alerted three times; At that point, you just call clearInterval to the value which has handle to setInterval and the job is finished.
Working code:
// value to output
var i = 0,
// starting setInterval and assigning its handle to variable interval,
// it is used to clear the interval when execution should be finished
interval = setInterval(function () {
// alert value of i and increase it by 1
alert(i++);
// if i is equals to 3, no more calls
if(i === 3) {
// clear the interval so method won't be called in the future
clearInterval(interval);
}
}, 2000);
JS FIDDLE EXAMPLE
Cheers, hopefully you learnt something new today.
Without forloop:
var number = 0;
var interval = setInterval(function(){
alert(number);
number++;
if(number === 3) {
clearInterval(interval);
}
}, 2000);
JSFIDDLE
1.1 Without for loop + without initial delay (demo):
var i = 0;
var showAlert = function(){
alert(i);
i++;
if(i < 3){
setTimeout(function(){
showAlert();
}, 2000);
}
};
showAlert();
1.2 Without for loop + with initial delay (demo):
var i = 0;
var showAlert = function(){
if(i < 3){
setTimeout(function(){
alert(i);
i++;
showAlert();
}, 2000);
}
};
showAlert();
2.1 With for loop + without initial delay (demo):
function setAlert(k){
setTimeout(function(){
alert(k);
},k * 2000);
}
for(var i = 0; i < 3; i++) {
setAlert(i);
}
2.2 With for loop + with initial delay (demo):
function setAlert(k){
setTimeout(function(){
alert(k);
},(k + 1) * 2000);
}
for(var i = 0; i < 3; i++) {
setAlert(i);
}
First of all, I would go with setTimout, you know that you want 3 alerts.
Second problem is a bit stranger. You are calling async function, setTimeout/setInterval and referring to the original i of the for loop inside of the setTimeout callback. That will not work because at the time of the timeout invocation the for loop has already finished and i var will be 3. One solution is to wrapp the async function in a self invoking anonymous function with params that you need inside async function. In our case we call it with i.
Solution:
for (i = 0; i < 3; i++) {
(function(i) {
setTimeout(function(){
alert(i);
}, 2000 * i);
})(i);
}
JS fiddle
I'm a bit confused as to how setTimeout works. I'm trying to have a setTimeout in a loop, so that the loop iterations are, say, 1s apart.
Each loop iteration makes an HTTP request and it seems like the server on the other end can't handle that many requests in such a short time span.
for (var i = 1; i<=2000 && ok; i++) {
var options = {
host:'www.host.com',
path:'/path/'+i
};
setTimeout(makeRequest(options, i), 1000);
};
Why does this not work and how can I achieve this?
Thank you
setTimeout is non blocking, it is asynchronous. You give it a callback and when the delay is over, your callback is called.
Here are some implementations:
Using recursion
You can use a recursive call in the setTimeout callback.
function waitAndDo(times) {
if(times < 1) {
return;
}
setTimeout(function() {
// Do something here
console.log('Doing a request');
waitAndDo(times-1);
}, 1000);
}
Here is how to use your function:
waitAndDo(2000); // Do it 2000 times
About stack overflow errors: setTimeout clear the call stack (see this question) so you don't have to worry about stack overflow on setTimeout recursive calls.
Using generators (io.js, ES6)
If you are already using io.js (the "next" Node.js that uses ES6) you can solve your problem without recursion with an elegant solution:
function* waitAndDo(times) {
for(var i=0; i<times; i++) {
// Sleep
yield function(callback) {
setTimeout(callback, 1000);
}
// Do something here
console.log('Doing a request');
}
}
Here is how to use your function (with co):
var co = require('co');
co(function* () {
yield waitAndDo(10);
});
BTW: This is really using a loop ;)
Generator functions documentation.
You need something like this
var counter = 5;
function makeRequst(options, i) {
// do your request here
}
function myFunction() {
alert(counter);
// create options object here
//var options = {
// host:'www.host.com',
// path:'/path/'+counter
//};
//makeRequest(options, counter);
counter--;
if (counter > 0) {
setTimeout(myFunction, 1000);
}
}
See also this fiddle
At the point of the alert(count); you can do your call to the server.
Note that the counter works opposite (counting down). I updated with some
comments where to do your thing.
Right now you're scheduling all of your requests to happen at the same time, just a second after the script runs. You'll need to do something like the following:
var numRequests = 2000,
cur = 1;
function scheduleRequest() {
if (cur > numRequests) return;
makeRequest({
host: 'www.host.com',
path: '/path/' + cur
}, cur);
cur++;
setTimeout(scheduleRequest, 1000)
}
Note that each subsequent request is only scheduled after the current one completes.
I might be late at the party but here is another (more readable) solution without the need to omit for loop.
What your code does is creating 2000 (actually 1999) setTimeout objects that will call the makeRequest function after 1 second from now. See, none of them knows about the existence of the other setTimeouts.
If you want them 1 sec apart from each other, you are responsible for creating them so.
This can be achieve by using your counter (in this case i) and the timeout delay.
for (var i = 1; i<=2000 && ok; i++) {
var options = {
host:'www.host.com',
path:'/path/'+i
};
setTimeout(makeRequest(options, i), i * 1000); //Note i * 1000
};
The first timeout object will be set for 1 second from now and the second one will be set for 2 seconds from now and so on; Meaning 1 second apart from each other.
I'm surprised that no one has mentioned this above, but it sounds like you need setInterval not setTimeout.
vat poller = setInterval(makeRequestFunc, 3000)
The code above will make a request every 3 seconds. Since you saved the object to the variable poller, you can stop polling by clearing the object like so:
cleanInterval(poller)
You're calling makeRequest() in your setTimeout call - you should be passing the function to setTimeout, not calling it, so something like
setTimeout(makeRequest, 1000);
without the ()
let i = 20;
let p = Promise.resolve(i)
while (i > 0) {
(i => {
p = p.then(() => {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(i);
resolve()
}, 2000)
})
})
})(i)
i--
}
p = p.then(data => console.log('execution ends'))
I'm very late on the subject (as usual ...;) but the only way I found to loop requests to a slow time response API and getting responses without HTTP 504 is using promises.
async function LoadDataFromAPI(myParametersArray) {
for(var i = 0; i < myParametersArray.length; i++) {
var x = await RunOneRequest(myParametersArray[i]);
console.log(x); // ok
}
}
The function called by the async function :
function RunOneRequest(parameter) {
return new Promise(resolve => {
setTimeout(() => {
request(parameter, (error, response, body) => {
// your request
});
resolve('ok);
}, 2000); // 2 secs
});
}
I want to write a for loop which prints number 1 to 10 with intervals after every iteration "like this"
How can I achieve it? I tried sleep() setInterval() setTimeout(") and what not but can't seem to find any working solution. And if possible I would like to do this using pure Javascript only.
function abc(){
for(i=1;i<=10;i++){
document.write(i+"<br>");
sleep(1000);
}
}
To answer the question, to get something like a sleep function you could just write somehting like this as a helper function
function sleep(dur) {
var d = new Date().getTime() + dur;
while(new Date().getTime() <= d ) {
//Do nothing
}
}
console.log(new Date().getTime())
sleep(1000)
console.log(new Date().getTime())
Then you could call the sleep function after every iteration like
function abc(){
for(i=1;i<=10;i++){
document.write(i+"<br>");
sleep(1000);
}
}
But Note that sleep will freeze your browser in this time and
you don't really wan't this kind of behaviour when you just want to periodiccally do sth
window.setInterval would be what you want in such cases
function abcd(i){
document.write(i + "<br>")
}
function repeatedTimeout(func,times,duration) {
var args = Array.prototype.slice.call(arguments).splice(3);
var i = 0;
args.push(i)
var wrap = function () {
if(args[args.length - 1] >= times)
window.clearInterval(wrap)
else {
func.apply(this,args)
args[args.length - 1]++
}
}
window.setInterval(wrap,duration)
}
repeatedTimeout(abcd,10,1000)
Which would call it 10 times every 1000 milliseconds, whithout freezing the Browers
Heres the JSBin
Update
If it really has to be a for loop, you could do something like this,
regardless of the sense it makes to me
for (var i = 0; i <= 10 ; i++) {
window.setTimeout(
(function (i){
return function() {
document.write(i + "<br>")
}
})(i),i * 1000)
}
In this case heres another JSBin
This would call window.setTimeout in a for loop and a multiple of the timeout with i as the timeout,
this would work, but i'd rather suggest using setInterval like you already did in the Fiddle you posted in the comment
Due to the mostly asynchronous (and single threaded) nature of JavaScript in the browser, constructs such as sleep() aren't the way to go.
You can write a generic function using setTimeout() that will do the looping and then pass in the function that should be run at every interval of x milliseconds. At least you'd have a reusable container in which you can run your code.
function loopn(n, fn, delay)
{
if (n > 0) {
fn();
if (n > 1) {
setTimeout(function() {
loopn(n - 1, fn, delay);
}, delay);
}
}
}
loopn(10, function() {
console.log('hello there');
}, 1000);
You could deconstruct the loop into a recursive function and use setTimeout to implement the pause.
var i = 0;
var limit = 10;
function loop(){
console.log(i);
i++;
if(i < limit)
{
setTimeout(loop, 100);
}
}
loop();