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.
setTimeout in JS
The main confusion you are having is pretty common and comes from the fact that you are using a loop. Everything outside of the timer callback is JavaScript that is being executed synchronously with no delay. The loop executes 5 times immediately when you run the code and so 5 instances of the timer callback function get placed on the event queue in a matter of milliseconds and it is from that point in time that all 5 timer callbacks are delayed, rather than one callback being delayed from the completion of the prior one.
The first instance of the callback then runs after its initial delay is reached (1 second), then the second instance runs after its delay (2 seconds, which is only 1 second later than when the first function call ran) and then the third one runs (which is only 1 second behind the previous one of 2 seconds) and so on.
What you need to do is place the first instance of the callback on the event queue with a 1 second delay before it runs and then, when that first instance has completed, place another instance on the event queue with a 2 second delay, and so on.
To do this, forget the loop and make the timer function recursive, which will essentially cause a repeating code call, just as a loop would.
let delay = 1000;
let timer = null; // Will hold a reference to the timer
function x() {
timer = setTimeout(function(){
console.log(delay / 1000);
delay += 1000;
if(delay > 5000){
clearTimeout(timer); // Cancel the timer
console.log("Operation Complete!");
} else {
// Because the next call for the parent function comes from within
// the timer callback function, it is delayed until the end of that
// callback function's execution.
x();
}
}, delay);
}
x();
setTimeout function not working with for loop
I got it working with this:
(Thanks Yotam Salmon for your answer, thats what helped me understand what I was doing wrong)
I basically got each function to set the timeout and run the following one, then i got the last one to run the first one again. all i needed then was to start the first one manually then it just ran forever.
function slide1to2(){ document.getElementById('slide1').className = "hidden"; setTimeout(slide2to3, 4000);}function slide2to3(){ document.getElementById('slide2').className = "hidden"; setTimeout(slide3to1, 4000);}function slide3to1(){ document.getElementById('slide1').className = ""; document.getElementById('slide2').className = ""; setTimeout(slide1to2, 4000);}
slide1to2();
div#slideshow{ width:100%; height:50%; background-image:url("white-wall.png");}
div#slideshow div{ width:100%; height:inherit; background-repeat:no-repeat; background-position:center; background-color:rgba(0,0,0,0.5); position:absolute; transition:1s;}
div#slideshow div[id$="1"]{ background:#FF8888; transform:translateX(0%); z-index:3;}
div#slideshow div[id$="2"]{ background:#88FF88; transform:translateX(0%); z-index:2;}
div#slideshow div[id$="3"]{ background:#8888FF; transform:translateX(0%); z-index:1;}
div#slideshow div[id$="1"].hidden{ transform:translateX(-100%);}
div#slideshow div[id$="2"].hidden{ transform:translateX(-100%);}
<div id="slideshow"> <div id="slide1"></div> <div id="slide2"></div> <div id="slide3"></div></div>
setTimeout executes after for loop in javascript
JS is sync. So all sync code is done first, and all async go in separate thread and they may finish earlier but they have to wait until all sync code is done.
setTimeout(function(){
console.log('setTimeout executes');
},1000); // this function go async in separate thread
for(var i=0;i<10000;i++){
console.log('inside for loop'); // sync
}
console.log('after For Loop'); // sync
// after all sync code async result will be called
// console.log('setTimeout executes'); will happen here
If you want full picture of how JS engines works read this. It is very basic and helps a lot. what is setTimeOut() function in javascript?
Not sure you what you want.
setTimeout
is a method of the global window object. It executes the given function (or evaluates the given string) after the time given as second parameter passed.
Read more about setTimeout
.
Why use setTimeout in deferred
The reason for doing this is to allow the javascript thread an opportunity to trigger any other events that may be waiting in the queue.
Javascript is single-threaded. If an event is triggered, it can only run when the currently running code has finished.
Using setTimeout
with a zero time delay effectively tells the JS interpreter that the callback
function call is part of a new context and that your current code block is finished. This means that JS will take the opportunity before calling callback()
to check to see if any other events need to be handled.
Although this may delay callback()
itself from being called immediately, this can be good for your site's overall performance:
Other events that may need to be handled include click events and other UI triggers. If you don't give them a chance to execute, it may make your user interface appear sluggish or non-responsive.
What is setTimeout doing when set to 0 milliseconds?
A few useful facts might help clarify what's happening:
- JavaScript is single-threaded. Asynchronous callbacks are assigned to a message placed in a message queue.
- When no code is currently executing, the event loop polls the message queue, requesting the next message in line to be processed (executed).
setTimeout
adds a message (with the callback provided) to the end of this queue after the specified delay has elapsed.
setTimeout
call is not a sure thing; it is the minimum delay before the callback is executed. The actual time taken depends on how long it takes to process any messages ahead of it in the queue.)So what happens if the delay is set to 0
? A new message is added to the queue immediately, and will be processed when the currently executing code is finished and any previously-added messages have been processed.
What's happening in your code
When you invokesetTimeout
…setTimeout(function() {
console.log('AAA');
}, 0);
…a message gets added to the queue with the specified callback. The rest of your code…for (i = 0; i < 1000; i++) {
console.log('BBB');
}
// etc.
…continues executing synchronously. Once it has completely finished, the event loop polls the message queue for the next message and finds the one with your setTimeout
callback, which is then processed (the callback is run).The callback only ever gets executed after the currently executing code has finished, no matter how long that takes.
Further reading
For more details on the event loop, see:- Concurrency model and event loop—MDN
- The JavaScript event loop: explained—Carbon Five
Why is setTimeout(fn, 0) sometimes useful?
In the question, there existed a race condition between:
- The browser's attempt to initialize the drop-down list, ready to have its selected index updated, and
- Your code to set the selected index
This race existed because JavaScript has a single thread of execution that is shared with page rendering. In effect, running JavaScript blocks the updating of the DOM.
Your workaround was:
setTimeout(callback, 0)
Invoking setTimeout
with a callback, and zero as the second argument will schedule the callback to be run asynchronously, after the shortest possible delay - which will be around 10ms when the tab has focus and the JavaScript thread of execution is not busy.The OP's solution, therefore was to delay by about 10ms, the setting of the selected index. This gave the browser an opportunity to initialize the DOM, fixing the bug.
Every version of Internet Explorer exhibited quirky behaviors and this kind of workaround was necessary at times. Alternatively it might have been a genuine bug in the OP's codebase.
See Philip Roberts talk "What the heck is the event loop?" for more thorough explanation.
How to create your own setTimeout function?
Just for the game since I really don't see why you couldn't use setTimeout...
To create a non-blocking timer, without using the setTimeout/setInterval methods, you have only two ways:
- event based timer
- run your infinite loop in a second thread
Event based timer
One naive implementation would be to use the MessageEvent interface and polling until the time has been reached. But that's not really advice-able for long timeouts as this would force the event-loop to constantly poll new tasks, which is bad for trees.function myTimer(cb, ms) {
const begin = performance.now();
const channel = myTimer.channel ??= new MessageChannel();
const controller = new AbortController();
channel.port1.addEventListener("message", (evt) => {
if(performance.now() - begin >= ms) {
controller.abort();
cb();
}
else if(evt.data === begin) channel.port2.postMessage(begin);
}, { signal: controller.signal });
channel.port1.start();
channel.port2.postMessage(begin);
}
myTimer(() => console.log("world"), 2000);
myTimer(() => console.log("hello"), 100);
Related Topics
Node.Js Piping the Same Readable Stream into Multiple (Writable) Targets
Bootstrap: Open Another Modal in Modal
How to Validate Google Recaptcha V2 Using JavaScript/Jquery
How to Unbind a Listener That Is Calling Event.Preventdefault() (Using Jquery)
Initializing Select with Angularjs and Ng-Repeat
Basic Authentication with Fetch
Differencebetween Settimeout(Fn, 0) and Settimeout(Fn, 1)
How to Reload/Refresh Jquery Datatable
Find the Exact Height and Width of the Viewport in a Cross-Browser Way (No Prototype/Jquery)
How to Export Socket.Io into Other Modules in Nodejs
Read a Text File Using Node.Js
How to Sort an Associative Array by Its Values in JavaScript
How to Auto-Slide the Window Out from Behind Keyboard When Textinput Has Focus
With JavaScript, How to Change the Z Index/Layer of an Svg <G> Element
Pass Parameter with Python Flask in External JavaScript
How to Build a Loop in JavaScript
Why Firefox Says That Window.Event Is Undefined? (Call Function with Added Event Listener)