Differences setTimeout () with setTimeout () in setTimeout () - javascript

what anyone could help me, I want to know the difference of:
setTimeout ("move ()", 3000);
with:
setTimeout (function () {setTimeout ("move", 3000)}, 100);
thanks to my friends who petrified answer.

First of all, the most important difference is in the actual useful code that is executed:
setTimeout ("move()", 3000); // executes move(); - a function call
setTimeout ("move", 3000); // executes move; - a statement that doesn't do anything
The second difference is in when the useful code is executed:
setTimeout ("move()", 3000); // move() gets called at T+3000
setTimeout (function () {setTimeout ("move()", 3000)}, 100); // move() gets called at T+3100
The last difference is also when the useful code is executed, but it is more subtile. JavaScript is single threaded, with an event loop. Timeouts can be considered events themselves as they participate in the same event loop as regular DOM events.
setTimeout (move, 3000);
The first code is straight forward. When that line is executed, a call to move is scheduled to be executed at least 3000ms after that time. The "at least" is important, because event handlers can be delayed by quite a while after they are supposed to be executed if the JS engine is busy executing other code.
setTimeout (function () {setTimeout (move, 3000)}, 100);
The second code is roughly the same, the same scheduling as before is scheduled to be executed *at least * 100ms after that line is encountered.
One example where execution can be delayed is this one:
setTimeout (function () {setTimeout (move, 3000)}, 100);
var d = new Date();
while ((new Date()).getTime() - 10000 < d.getTime()) ; // busy wait for 10 seconds
As explained before, some code (doesn't matter what) is scheduled to be executed after at least 100ms. For the next 10 seconds however, the browser is busy executing the while. After the 10 seconds pass, the brower is ready to treat other events, like the scheduled code. In total, the move function gets called (at least) 13 seconds after the first call to setTimeout.
To conclude, the differences are subtile and there is nothing that would justify a call to setTimeout inside another call to setTimeout in a simple scenario as above. If the program logic demands it, there is also nothing inherently bad.

Interesting question , two difference
First let us define:
Method A: setTimeout ("move ()", 3000);
Method B: setTimeout (function () {setTimeout ("move", 3000)}, 100);
1.Different compile order by javascript vm
For A javascript try to compile the str into runnable code and run it after 3000 milliseconds, versus B try to compile the the function into runnable code instantly , but run it after 3000 milliseconds.
Try following demo:
setTimeout ('alert("A")', 3000);
// "A" alerted after 3000 milliseconds
setTimeout (alert('B')||function(){alert('C')}, 3000);
// "B" alerted instantly, while C alerted after 3000 milliseconds
2.Different usage scope
B can have a larger usage scope, for B can carry any variable for function as context by using closure, but A just only have the context of window or document.
Try following demo:
(function(){var va = 1; setTimeout ('alert(va)', 3000)}());
// run into error:Uncaught ReferenceError: va is not defined after 3000 milliseconds
(function(){var vb = 1; setTimeout(function(){alert(vb)}, 3000);}());
// 1 alerted after 3000 milliseconds

Related

Javascript Deep thinking: Recursive setTimeOut function with a clearTimeout call on a button pressed?

I have a quick question about using recursive setTimeOut recursively and a clearTimeOut that get called somewhere else.
On rare cases, will there ever gonna be a bug where clearTimeOut doesn't actually stop the loop? Is it possible that the timeOutID get changes into a new value and clearTimeout is called on the old value?
Here is the code:
timeOutID = 0;
function timeOutRecusive() {
timeOutID = setTimeout('timeOutRecusive();', 1000);
}
function killTimeOutRecusive() {
clearTimeout(timeOutID);
}
//when page started.
start() {
timeOutRecusive();
}
//When a button is press, calls killTimeOutRecursive();
EDIT: I have some typo in my code. It should be 'timeOutID' instead of clockID. clearTimeOut should be 'clearTimeout' (using its built-in)
This approach is pretty bullet-proof, and a standard practice.
Is it possible that the timeoutId get changes into a new value and clearTimeout is called on the old value?
No, this is not possible. JS code doesn't run in parallel, there are no data races from multithreading.
The only edge case where killTimeoutRecursive does not work as expected is when it is called from within timeoutRecursive, after the old timeout occurred and before the new one was created:
var timeoutId = 0;
function timeoutRecusive() {
callback();
timeoutId = setTimeout(timeOutRecusive, 1000);
}
function killTimeoutRecusive() {
clearTimeout(timeoutId);
}
function callback() { // this might be user-provided
killTimeoutRecursive();
}
Your thought is legit. If the callback method of the specified timeout would be called in a parallel execution, it could just create a new timeout (not yet updated the variable) while you try to clear the current timeout.
However, the timeout handling is executed sequential. (thats why it some times can take way longer than 1000ms for the callback to be fired)
Meaning:
-If your code is just about to create a new timeout, your clear call "waits" and then clears the 3ms old timer.
-If you are just about to clear the timeout, when 1000 ms have elapsed, the callback will not be fired, as long as your code is busy. And when its cleared, it wont be added to the event queue anymore, when the timeout is executed after delayed 1004ms.
No.
Ignoring the fact there is no clearTimeOut function (it's clearTimeout) and it's being called with clockID, not timeOutID), all of these statements will be run sequentially; any tasks that setTimeout and friends might run will be only run after the current synchronous block of JavaScript is run, i.e. the sequence would be something like
[frame]
start()
setTimeout(...)
clearTimeout(...)
[frame]
(this is where timeout functions could be run)

javascript setInterval() collision between the delay and execution time

Is there a way to avoid the conflict between the delay and execution time if the time of execution was longer than the delay using setInterval()?
For example:
setInterval(function(){
// some code that takes 300 ms to be executed
// which it's longer than the delay 200 ms
}, 200);
I already found the alternate way, which is to use setTimeout() with recursion to ensure that the delay will start immediately after the function is executed, but my question is about setInterval(), not replacing it with setTimeout()
I'm not sure what is your concern.
Javascript is always single-threaded that means that in time of execution of the function called by setInterval no other function will be executed and no re-run of setInterval may happen!
Naturally if in your setInterval called function you use deferred calls you enable the function to finish and be executed again.
To protect against such problem you may use a simple semaphore like:
var inProcessing = false ;
setInterval(function(){
// some code that takes 300 ms to be executed
// which it's longer than the delay 200 ms
if (!inProcessing){
inProcessing = true ;
$http.get(...).then(function(){inProcessing = false;...},
function(){inProcessing = false;...});
}
}
}, 200);
You cannot do this using setInterval, only setTimeout. If your problem is the lack of easy cancellation of the setTimeout method, you can use the following:
var timeout = setTimeout(function runMe(){
// some code that takes 300 ms to be executed
timeout = setTimeout(runMe, 200);
}, 200);
// somewhere else
clearTimeout(timeout);
You can use a nested setTimeout instead of setInterval. Hope you enjoy !
https://javascript.info/settimeout-setinterval
I'm assuming you just want to postpone a cycle of setInterval if the code from a previous run isn't complete.
var starts = 0;
var ends = 0;
function myFunc () {
starts++;
//doStuff
ends++;
}
setInterval(function () {
if (starts === ends) {
myFunc();
}
}, 200);

Delay jquery function inside the function?

Is it possible to make a function 'idle' for a couple of seconds while it is being executed?
I tried with
setTimeout( function(){
$("#nytLevel").hide();
} , 3000 );
But the rest of the function would just executed.
Below the setTimeout I start a function
function timer(){
myVar = setTimeout( function(){
console.log("SLOW");
} , 10000 );
}
but when 10 seconds have passed it'll console log "SLOW", but it should console log it 13 seconds after because I've put a setTimeout to 3 seconds.
setTimeout() just schedules something to run in the future and the rest of your Javascript continues to run. It does not block further Javascript execution. This is often called an "asynchronous" operation. It runs in the background and will call a callback sometime in the future when it has completed its work. It is also referred to as "non-blocking" because it does not block the rest of your Javascript execution.
Anything you want to not run until the setTimeout() fires must be put inside the setTimeout() callback or called from there.
// define function
function timer(){
myVar = setTimeout(function() {
console.log("SLOW");
}, 10000);
}
// schedule first timer
setTimeout(function() {
$("#nytLevel").hide();
// now start second timer
timer();
}, 3000);
It's worth mentioning that jQuery has a .delay() method that works with animations and other functions put in the queue and it can sometimes streamline your code. In the case above, you could do this:
$("#nytLevel").delay(3000).hide().delay(10000).queue(function(next) {
console.log("SLOW");
next(); // keep the queue moving in case there's something else in the queue
});
Please note that .delay(xxx) only works with jQuery methods that themselves use the queue (such as animations) or with methods you put in the queue yourself using .queue() (as I've shown above).
setTimeout() is an asynchronous function, meaning that code will not pause until the setTimeout() time is completed. If you want code to be delayed along with the setTimeout(), you can put the other code inside of the initial setTimeout()
setTimeout( function(){
$("#nytLevel").hide();
myVar = setTimeout( function(){
console.log("SLOW");
} , 10000 );
} , 3000 );
I wouldn't recommend this, but you could fashion a recursive function to do what you wanted, using a flag to dictate before or after timeout. In the below example you'd call it like this runAfterTimeout() or runAfterTimeout(false)
function runAfterTimeout(run) {
if (! run) {
console.log('about to wait 10 seconds');
setTimeout(function(){runAfterTimeout(true)},10000);
return;
}
console.log('this section runs after 10 seconds');
setTimeout(function(){$("#nytLevel").hide();},3000);
}
Fiddle: https://jsfiddle.net/m9n1xxra/
Bear in mind, timeouts are not 100% accurate. The engine will look for an appropriate break in execution to execute what you want, but if the engine is in the middle of something else, that will execute first.

Javascript Delay

I understand that Javascript does not have a delay(500) method, which would delay execution for 500 milliseconds, so I have been trying to get around that by using setTimeout and setInterval.
for(var i =0; i< 10; i++){
/* Animation Code */
var doNothing = function(){var m =5;}
setTimeout(doNothing, 50);
}
However, this does not seem to work. I essentially want some code that stops the execution for n milliseconds and then continues execution.
Practically speaking, you can't do this. Deal with it and find a callback-based way instead. Typically this means putting everything that should happen after the delay in the callback itself.
For example, you can't do this to make baz wait:
foo();
setTimeout(function() {
bar();
}, 500);
baz();
so you do the only thing you can:
foo();
setTimeout(function() {
bar();
baz();
}, 500);
The setInterval() Method wait a specified number of milliseconds, and then execute a specified function, and it will continue to execute the function, once at every given time-interval.
Syntax
window.setInterval("javascript function",milliseconds);
The window.setInterval() method can be written without the window prefix.
The first parameter of setInterval() should be a function.
How to Stop the Execution?
The clearInterval() method is used to stop further executions of the function specified in the setInterval() method.
Syntax
window.clearInterval(intervalVariable)
The window.clearInterval() method can be written without the window prefix.
To be able to use the clearInterval() method, you must use a global variable when creating the interval method:
myVar=setInterval("javascript function",milliseconds);
Then you will be able to stop the execution by calling the clearInterval() method.
good refrence
If you came from the language/framework/API background, where you could suspend the execution with something like Sleep, or process user input synchronously with something like DoEvents, it won't work in JavaScript.
There is no way you can block the JavaScript event loop with something like this, for a good reason: UI responsiveness. In JavaScript, everything is asynchronous. You can use setTimeout to do something upon a timer event, but the user is still able to access the UI between the timer events or even navigate away from the page.
To address your code fragment, what you are looking for is called an asynchronous state machine. It allows to preserve the state of the code between stop/continue (in your case, it's the state of the animation, although i variable is also a part of it):
(function()
{
var i = 0;
var nextStep = function()
{
if (i<10)
{
/* Animation Code */
i++;
setTimeout(nextStep, 500);
}
}
nextStep();
})();
It will be much easier to code when all browsers support the new yield keyword:
http://pag.forbeslindesay.co.uk
On a side note, some other answers suggest using setInterval. There is a subtle but important difference between delay and interval. Delay is the time between two steps. Interval is the time since the previous step started. If each step of animation takes 200ms, and you use the interval of 500ms, the actual delay between two steps will be 300ms, not 500ms as probably expected.
setInterval() - executes a function, over and over again, at specified time intervals
To pass a function as a string, be sure to append the function name with parentheses.
window.setInterval("someFunction()", 5000);
When passing a function pointer, do not include the parentheses.
window.setInterval(someFunction, 5000);
var timer_id=setInterval(doNothing,500);
If you want to stop the execution
make the timer_id variable global
clearInterval(timer_id);
Much cleaner and readable code would be if you use RxJS
Here is an example:
Rx.Observable
.interval(1000)
.take(10)
.subscribe((x) => console.log(`${x}: ${new Date().toLocaleTimeString()}`))
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.lite.min.js"></script>
interval - is a time delay between your animation calls. In my example
it's 1000ms
take - number of times to execute subscribe - is function
that will be called every 1000ms for 10 times (in your case it will be
your animation code)
Here some something that could help.
function delay( s , callback )
{
var fct_ref = "tmp_" + Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 6).toUpperCase();
var tmp_fct = ( callback !== undefined ) ? callback.toString().match(/^[^{]+\{(.*?)\}$/)[1] : "";
document.getElementsByTagName("body")[0].insertAdjacentHTML("beforeend","<div id='"+fct_ref+"' style='background-color:transparent;color:transparent;position:absolute;top:"+window.scrollY+"px;left:"+window.scrollX+"px;opacity:1;transition:all "+s+"s'>-</div>");
var func = new Function("return function transition"+fct_ref+"(e){ e.target.removeEventListener('transitionend' , transition"+fct_ref+", false ); "+tmp_fct+" ; document.getElementById('"+fct_ref+"').parentNode.removeChild(document.getElementById('"+fct_ref+"')); };")();
document.getElementById(""+fct_ref).addEventListener("transitionend", func , false );
document.getElementById(""+fct_ref).offsetHeight;
document.getElementById(""+fct_ref).style.opacity="0";
}
delay(1, function() { console.log("ANIMATION_1"); } );
delay(3, function() { console.log("ANIMATION_3"); } );
delay(5, function() { console.log("ANIMATION_5"); } );

Putting a 10 second pause in xmlHttpRequest submit

This javascript code is fairly lengthy, but the most important part is the end where it posts:
httpwp['send'](paramswp);
I have tried without success to put a 10 second pause between each send. Normally it sends them all instantly.
full code http://pastebin.com/cEM7zksn
To delay 10 seconds before calling this, you could use setTimeout
setTimeout(function() { httpwp['send'](paramswp); }, 10000);
Or more simply:
setTimeout(function() { httpwp.send(paramswp); }, 10000);
The setTimeout() function does not pause execution for the specified time, it queues a function to be executed after the specified time. The line of code after setTimeout() will be executed immediately. So if you have the following code:
1 someFunction();
2 setTimeout(function(){console.log("From timeout");}, 10000);
3 console.log("After setTimeout()");
What will happen is on line 1 someFunction() will be called, then on line 2 an anonymous function will be queued to execute in 10 seconds time, then line 3 will execute, logging "After setTimeout()", and finally 10 seconds later the anonymous function will execute logging "From timeout".
If you want to code a loop where each iteration is spaced out by 10 seconds, rather than using a conventional for loop you write a function that uses setTimeout() to call itself:
// this for loop won't work
for(var i = 0; i < 20; i++) {
// do something
// pause for 10 seconds ---- can't be done
}
// so instead you do something like this:
function timeoutLoop(i, max) {
if (i < max) {
// do something
i++;
setTimeout(function(){timeoutLoop(i, max);}, 10000);
}
}
timeoutLoop(0, 20);
I found your code a little hard to read so I've not tried to integrate the above with it, but here is a really simple demo of the above working: http://jsfiddle.net/CrSEt/1/
Or here is a cleaner version that separates the actual processing from the loop function by using a callback: http://jsfiddle.net/CrSEt/
I'm sure if you play around a bit with the above you'll see how to get it to work in your code. You may want to consider setting subsequent timeouts from inside your ajax success callback.

Categories

Resources