Say I want to do something after 10000ms, but do something else during that 10000ms. How should I use JavaScript to implement this? Thanks.
Just place the code immediately after the call to setTimeout():
setTimeout(function(){
// Code to be executed after timeout goes here
}, 10000);
// Code to be executed immediately goes here
After you call the setTimeout() the code continues. So it will happen before the setTimeout() fires.
setTimeout() call is asynchronous and you can't say that do this thing in first 1000ms and then do that was given to setTimeout. When callback given to setTimeout will be executing, another code will also be executing.
e.g.
// some statements
setTimeout(function(){
// code that will be executed after 1000ms
}, 1000);
// some more statements that will be executed before above callback
// unless there are too many lines that are taking more than 1000ms,
// Then in that case, above callback execution will not block the
// global/main scope execution.
The code in your function runs until it ends, so put anything you want to run before the interval after the settimeout. The timeout will only be called at the end of the function event if it would be set to 0ms.
function(){
<code>
settimeout(function(){
<code>
}, 10000)
<code you want to rum>
}
Related
setTimeout(function(){
console.log("m");
}, 0);
console.log("s");
Why does this code print "s" before "m", even if the setTimeout callback is supposed to wait for 0 ms?
A browser or node.js always run a single threaded event loop to run your code. On the first run it will always run your synchronous code but may also que up asynchronous events that will call back later. Thats why we call the function here callback function it will be called later.
setTimeout is a microtask.
That means the function that you see isnt gona executed immedantly, it is gonna first queued up and will be executed within the next event loop.
Also a sidefact: 0 ms just means it will minimum wait 0 ms not exact 0
When you create a promise, or call an async function, or set a timeout for 0 milliseconds, the function is immediately queued into the Javascript event loop. Essentially, the function is added to a queue of functions to call, and once the javascript interpreter has nothing to do it'll start calling those functions. So, when you set a timeout for 0 milliseconds, it queues the console.log("m"), then calls the console.log("s"), then it has nothing to do so it finishes the queued console.log("m"), which is why it's out of order.
it just because JS is single-threaded and event loop works that way.
setTimeout has written in a way that it will send you function or whatever you want to do in a callback queue.
and then move forward to the next line, once next line executed it will not run your setTimeout part, or in other words, it will not process the setTimeout part until the stack is not empty.
so this is your code, and it will execute like this.
setTimeout(function () {
console.log("m");
} , 0)
console.log('s');
the first line will execute and it will send the inner part of setTimeout to callback queue and move to the 2nd line.
while 2nd line is executing the setTimeout part will wait till the stack is not emplty and as soon as 2nd line finishes execution,
the setTimeout part will execute,
maybe it's confusing by words, let's see this in action. I bet you can not get a better example than this to understand it, it's explained in the best way by Philip robert.
because JS code goes in order one by one. When you specifying setTimeout to 0 is still waiting, in C++ lang this would be something like this 0.000000245ms, and JS runs often on C++/C browser.
try this simple example
for (let x = 0; x < 500; x++) {
setTimeout(() => console.log(x), 0);
}
console.log('hello');
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)
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.
I want to call a function in JavaScript continuously, for example each 5 seconds until a cancel event.
I tried to use setTimeout and call it in my function
function init()
{ setTimeout(init, 5000);
// do sthg
}
my problem is that the calls stops after like 2 min and my program is a little bit longer like 5 min.
How can i keep calling my function as long as i want to.
thanks in advance
The only conceivable explanations of the behavior you describe are that:
As another poster mentioned, init is somehow getting overwritten in the course of executing itself, in the // do sthg portion of your code
The page is being reloaded.
The //do sthg code is going into some kind of error state which makes it looks as if it not executing.
To guarantee that init is not modified, try passing the // do sthg part as a function which we will call callback:
function startLoop(callback, ms) {
(function loop() {
if (cancel) return;
setTimeout(loop, ms);
callback();
}());
}
Other posters have suggested using setInterval. That's fine, but there's
nothing fundamentally wrong with setting up repeating actions using setTimeout with the function itself issuing the next setTimeout as you are doing. it's a common, well-accepted alternative to setting up repeating actions. Among other advantages, it permits the subsequent timeouts to be tuned in terms of their behavior, especially the timeout interval, if that's an issue. If the code were to be rewritten using requestAnimationFrame, as it probably should be, then there is no alternative but to issue the next request within the callback, because requestAnimationFrame has no setInterval analog.
That function is called setInterval.
var interval = setInterval(init, 5000);
// to cancel
clearInterval(interval);
I have created a JavaScript version of the Little Man Computer based on the Java one at http://www.atkinson.yorku.ca/~sychen/research/LMC/LMCHome.html
I have it working in by stepping through each instruction. I have a function called stepCode() that does this.
What I want is a function that will run the program, pausing for a second between each step until the simulated program ends.
The code I have is this:
function runProgram()
{
var milliseconds = 1000;
var timeOut;
programRunning = true;
while(programRunning)
{
timeOut = setTimeOut(stepCode(), milliseconds);
}
}
This seems does not work. It still performs all the stepCode() calls one after the other very quickly. I want to pause between each stepCode() call.
I'm obviously doing something wrong. Any ideas?
You should use setInterval instead of setTimeout. Additionally, you need to reference the function, not call the function:
var timeOut; // global timeout variable to ensure both methods have access to it.
function runProgram() {
var milliseconds = 1000;
timeOut = setInterval(stepCode, milliseconds); // use setInterval instead of setTimeout
}
function stepCode {
// ... code processing here ...
// I assume you are setting programRunning to false at some point in this method.
// Instead of setting programRunning = false, you would do:
clearInterval(timeOut);
// Note, if you only have one timeout interval set, you can use clearInterval();
}
setInterval will cause the stepCode function to run every 'milliseconds' until you call clearInterval(timeOut);; setTimeout will only queue it up once. Anything that is queued via setTimeout will not execute until the current flow of code has been completed. As a result, programRunning will run and queue up several setTimeout executions. Once the programRunning variable hit false, the current code flow will finish and ALL of the queues will wait 1 second, and effectively execute all at the same time, or in rapid succession.
When you pass in a method call (e.g. stepCode()), it will call the method. You have to pass a reference to the function stepCode (notice no parens), to ensure that it knows what to run each time it executes.
This Fiddle Demo simulates a counter, which is common thing people attempt to execute using setInterval. It demonstrates the basic concept and use of setInterval.
In addition to suggested setInterval use that will call stepCode at 1 second intervals until cleared (or until the page is reloaded), and correction of removing () after stepCode that results in immediate stepCode executon, you can still use setTimeout if they are chained as shown below. Depending on what stepCode does and how long it takes, this solution has an advantage of ensuring that there is 1 second of idle time between the end of the previous and the beginning of the next stepCodes.
var milliseconds = 1000;
function runProgram()
{
programRunning = true;
stepCodeWrapper();
}
function stepCodeWrapper() {
if (programRunning) {
stepCode();
setTimeOut(stepCodeWrapper, milliseconds);
}
}
Just try with:
timeOut = setInterval(stepCode, milliseconds);
Bic, thanks for your swift response. You are correct about the programRunning flag being set to false inside the stepCode() function. I've set it as a global variable so that I could possibly halt the program by pressing a button, but thats another problem.
Tried both setInterval and setTimeout. You are right about it repeatedly calling the function. Using either method locks up the browser with repeated function calls. This is probably as its in a while loop. I cannot think of another was to repeatedly call the stepCode() function otherwise.
I sort of understand the difference between setInterval & setTimeout. Thanks, and I understand that would make the while loop redundant, but then how to stop it calling the stepCode function when the programRunning flag is set to false?