Reputation: 26008
I want to create a delay in a loop depending on a condition. Say, I have this:
var maxLoops = 50;
var counter = 0;
(function next() {
if (counter++ >= maxLoops) {
return;
}
setTimeout(function() {
console.log(counter);
next();
}, 100);
})();
Is there any way to pause the process for 2 seconds only when the counter is equal to 10, 20 or 30? So it should print:
1....10
(delay for a custom period of time)
11....20
(delay for a custom period of time)
21....30
(delay for a custom period of time)
31...50
The bottom line is, I don't want to delay at all when the counter isn't equal to 10, 20, 30.
Upvotes: 0
Views: 73
Reputation: 707218
You can just use the setTimeout()
with a different timing based on your counter:
var maxLoops = 50;
var counter = 0;
(function next() {
if (counter++ >= maxLoops) {
return;
}
var delay = 0;
// on multiples of 10, use a longer counter
if (counter % 10 === 0) {
delay = 2000;
}
setTimeout(function() {
console.log(counter);
next();
}, delay);
})();
Or, you could skip the setTimeout()
completely when you don't need the delay.
var maxLoops = 50;
var counter = 0;
(function next() {
if (counter++ >= maxLoops) {
return;
}
// on multiples of 10, use a longer counter
if (counter % 10 === 0) {
setTimeout(function() {
console.log(counter);
next();
}, 2000);
} else {
console.log(counter);
next();
}
})();
Or, rather than recursion, you can just use a while loop as in this working snippet:
var maxLoops = 50;
var counter = 0;
(function next() {
// while we haven't hit maxLoops and while not a multiple of 10
while (counter < maxLoops && counter % 10 !== 0 && counter !== 0) {
log(counter);
++counter;
}
if (counter < maxLoops) {
setTimeout(function() {
log(counter);
++counter;
next();
}, 1000);
}
})();
function log(x) {
var div = document.createElement("span");
div.innerHTML = x + " ";
document.body.appendChild(div);
}
Upvotes: 1
Reputation: 13600
Sure you can do that just change the timeout when you have a multiple of 10.
var maxLoops = 50;
var counter = 0;
(function next() {
counter += 1
var timeout_duration = counter % 10 == 0 ? 2000 : 0;
if (counter >= maxLoops) {
return;
}
setTimeout(function() {
console.log(counter);
next();
}, timeout_duration);
})();
That said, there need some few improvments because maxLoops and counter are defined on the global scope. Make it a function.
function loop (maxLoops, start) {
var counter = start || 0;
(function next() {
counter += 1
var timeout_duration = counter % 10 == 0 ? 2000 : 100;
if (counter >= maxLoops) {
return;
}
setTimeout(function() {
console.log(counter);
next();
}, timeout_duration);
})();
}
loop(50);
If you don't want to call next
when counter isn't a multiple of 10, then you can add a usual loop in between the calls.
function loop (maxLoops, start) {
var counter = start || 0;
var timeout_duration = 2000;
(function next() {
while(counter < maxLoops && counter % 10 != 0) {
counter += 1
}
if (counter >= maxLoops) {
return;
}
setTimeout(function() {
console.log(counter);
next();
}, timeout_duration);
})();
}
loop(50);
That said, keep in mind that a setTimeout
of 2000
doesn't mean exactly 2 seconds, but not less than 2 seconds. If somehwere, there is a loop that breaks the thread, the setTimeout
could be never called as Javascript is single threaded and there is no fact that the function will be called after 2 seconds. If you're planning to use setTimeout
to measure something within time, you might have to plan something else that will include the Date
object for timings.
Upvotes: 5