setInterval' vs 'setTimeout'
setTimeout(expression, timeout);
runs the code/function once after the timeout.
setInterval(expression, timeout);
runs the code/function repeatedly, with the length of the timeout between each repeat.
Example:
var intervalID = setInterval(alert, 1000); // Will alert every second.
// clearInterval(intervalID); // Will clear the timer.
setTimeout(alert, 1000); // Will alert once, after a second.
javascript - setTimeout() vs setInterval()
The main diffrence is
setInterval fires again and again in intervals, while setTimeout only fires once.
you can get more differnces in simple words in
setTimeout or setInterval?
'setInterval' vs 'setTimeout'
setTimeout or setInterval?
They essentially try to do the same thing, but the setInterval
approach will be more accurate than the setTimeout
approach, since setTimeout
waits 1000ms, runs the function and then sets another timeout. So the wait period is actually a bit more than 1000ms (or a lot more if your function takes a long time to execute).
Although one might think that setInterval
will execute exactly every 1000ms, it is important to note that setInterval
will also delay, since JavaScript isn't a multi-threaded language, which means that - if there are other parts of the script running - the interval will have to wait for that to finish.
In this Fiddle, you can clearly see that the timeout will fall behind, while the interval is almost all the time at almost 1 call/second (which the script is trying to do). If you change the speed variable at the top to something small like 20 (meaning it will try to run 50 times per second), the interval will never quite reach an average of 50 iterations per second.
The delay is almost always negligible, but if you're programming something really precise, you should go for a self-adjusting timer (which essentially is a timeout-based timer that constantly adjusts itself for the delay it's created)
setInterval vs setTimeout which is better to run a loop at a specified speed
You can use async/await to emulate typing and create delays:
//
// Async timeout function
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));
//
// Bot typing function
const runBot = text => {
// Use promises
return new Promise(async (resolve, reject) => {
// DOM
const div = document.getElementById('text');
// Create chars array
const chars = text.split('');
// Wait 1 sec before typing
await timeout(1000);
// Type text
while(chars.length) {
// Put one char at iteration
div.innerHTML += chars.shift();
// Wait some amount
await timeout(100);
}
// Add new line to the text box
div.innerHTML += '<br>'
// Finish function
return resolve();
});
}
//
// Text typing runner and button controller
const typeText = async text => {
// DOM
const button = document.querySelector('button');
// Disable button
button.disabled = true;
// Run bot and wait till it finishes
await runBot(text);
// Enable button
button.disabled = false;
}
<div id="text" style="padding:10px;border:1px solid #000"></div>
<button onClick="typeText('This is demo text!')">Start bot</button>
How to deal with setTimeout in setInterval within a closure
Using setTimeout
will not solve your problem. It's just logical. What setTimeout
does is delay execution of something. So if you have a setInterval
100 times per second (every 10 milliseconds) and you call setTimeout
inside it all you are doing is call setTimeout
100 times per second which will still print hello world
100 times per second:
100 times per second 100 times per second
setInterval
setInterval ╲
setInterval ╲╲
. ╲╲╲ 1 second later
. ╲╲╲
. ╲╲╲
╲╲╲______________ setTimeout
╲╲______________ setTimeout
╲______________ setTimeout
.
.
The solution is to count how many time you've been called and print hello world
every 100 times setInterval
calls your function. Let's start with the most simple way to do this: global variables:
var counter = 0;
function doSth(fn) {
counter ++;
if (counter >= 100) { // once per second
counter = 0;
fn();
}
}
This works, however we've introduced a global variable which is ugly. Fortunately we know that the setInterval
will not be calling our function directly. Instead it expects our function to return another function which it will call:
const fn = doSth(...);
Which means we need to write our function like this:
var counter = 0;
function doSth(fn) { // <──┐
return function(){ // <──┴─ oh look, a closure!
counter ++;
if (counter >= 100) { // once per second
counter = 0;
fn();
}
}
}
This is very fortunate because closures are a mechanism that allows functions to share local variables. Basically it makes local variables behave a bit like global variables but does not pollute the global namespace. Now we can simply move the global variable into the closure:
function doSth(fn) {
var counter = 0;
return function(){
counter ++;
if (counter >= 100) { // once per second
counter = 0;
fn();
}
}
}
setTimeout inside setInterval does not work well
- The interval starts
- 1 second later the interval resolves:
- classes are switched over
- the timeout is triggered
- 1 second later:
- The timeout resolves
- classes are switched over
- The interval resolves
- classes are switched over
- the timeout is triggered
- The timeout resolves
You probably want the timeout time to be half the interval time, not the same as it.
A better approach entirely would be to use one class and use jQuery().toggle
to toggle it on and off every second (using one interval and no timeouts).
Which is better between setTimeout and setInterval?
setInterval
is good if you don't care too much about accuracy, e.g. polling for some condition to be met.
setTimeout
is good if you want a one–off event or need to adjust the interval between calls, e.g. a clock that should update as close as possible to just after the next whole second.
Both can be used for events that run continuously at approximately the specified interval, both can be cancelled, both only run at about (as soon as possible after) the designated time interval.
Incidentally, the first code example in the OP should not cause a stack overflow, though it is otherwise not very well written.
Related Topics
Creating Multiline Strings in JavaScript
Get Difference Between 2 Dates in JavaScript
How to Read a Local Text File in the Browser
Correct Modification of State Arrays in React.Js
How to Get a Subset of a JavaScript Object'S Properties
Working With $Scope.$Emit and $Scope.$On
How to Convert Decimal to Hexadecimal in JavaScript
How to Get the Full Object in Node.Js'S Console.Log(), Rather Than '[Object]'
What Is Event Bubbling and Capturing
Abort Ajax Requests Using Jquery
When Is JavaScript'S Eval() Not Evil
Wait Until All Jquery Ajax Requests Are Done
Is It an Anti-Pattern to Use Async/Await Inside of a New Promise() Constructor
How to Get All Properties Values of a JavaScript Object (Without Knowing the Keys)