Javascript Delay - javascript

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"); } );

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 and clearInterval, which way is correct?

Which way is correct and more efficient in using setInterval() and clearInterval()?
1.
something = setInterval(function() {
try {
...load something
clearInterval(something);
} catch (e) {
// error
}
}, 5000);
2.
something = setInterval(function() {
try {
...load something
} catch (e) {
// error
}
}, 5000);
setTimeout(something, 7000);
EDIT:
For #2, I meant setTimeout() instead of clearInterval().Has been changed.
I assume the interval you're passing into clearInterval is meant to be something.
Your second example will never fire your timer, because you clear the timer immediately after setting it. You're also passing an argument (7000) into clearInterval that won't get used (clearInterval only accepts one argument).
Your first example is right provided that you want to clear the repeated timer at the point where you're calling clearInterval from within the handler. Presumably that's in an if or similar, because if you want a one-off timed callback you'd use setTimeout, not setInterval.
EDIT:
For #2, I meant setTimeout() instead of clearInterval().Has been changed.
That completely changes the question. No, that's not correct. setInterval schedules the function to be called repeatedly on the interval you give it, you don't pass its return value into setTimeout.
If you need something to happen over and over again you use setInterval if you only need it to happen once use setTimeout (you can simulate setInterval by chaining multiple timeouts one after the other). Timeouts only happen once therefore you do no need to clear them. Also clearInterval does not take a time argument so the interval you set will be cleared before it ever executes since classic javascript is synchronous.
just to complete the answer, take many care with setInterval(). if your "...load something" take sometime more time to load than the time according (for a reason or another). it will just don't do it for this time and will wait the next call of setinterval.
I encourage to use setTimeout() as much as possible instead.
You can find find below the use cases that are, according to me, aswering to your questions:
For your case 1:
var something = setInterval(function() {
// Do stuff, and determine whether to stop or not
if (stopCondition) {
clearInterval(something);
}
}, 5000);
For your case 2:
var something = setInterval(function() {
// Do stuff
}, 5000);
// Pass a function to setTimeout
setTimeout(function() {
clearInterval(something);
}, 17000);

Pause JavaScript - setTime

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?

suspend setInterval

I use setInterval to run a function (doing AJAX stuff) every few seconds. However I also have an other function also calling it.
setInterval(myFunc(), 5000);
function buttonClick() {
// do some stuff
myFunc();
}
Most of the time it works, however sometimes this function gets called twice at the same time resulting in receiving exactly the same result twice, something I don't want.
I think I have to use clearTimeout:
var interval = setInterval(myFunc(), 5000);
function buttonClick() {
clearTImeout(interval);
// do some stuff
myFunc();
interval = setInterval(myFunc(), 5000);
}
However this causes the function to halt. Since it gets called from an other function some code never gets executed. How can I prevent this?
however sometimes this function gets called twice at the same time resulting in receiving exactly the same result twice, something I don't want.
JavaScript on browsers is single-threaded (barring using the new web workers stuff, but that wouldn't apply here anyway). Your function will never get called while it's running. (But more below.)
In your various code quotes, you're calling myFunc where you mean to just be referring to it. E.g.:
var interval = setInterval(myFunc(), 5000);
should be
var interval = setInterval(myFunc, 5000);
// ^--- No parentheses
Your code cancelling the timeout will work if you correct that:
var interval = setInterval(myFunc, 5000);
function buttonClick() {
clearTImeout(interval);
// do some stuff
myFunc();
interval = setInterval(myFunc, 5000);
}
But there's no reason to do that, myFunc cannot get called while it's running anyway.
If myFunc is triggering something that will complete asynchronously (an ajax call, for instance), the above won't help (for the simple reason that myFunc will start the process and then return; the process will complete separately). In that situation, your best bet is to have myFunc schedule its next call itself:
function myFunc() {
// Do my work...
// Schedule my next run
setTimeout(myFunc, 5000);
}
...and not use setInterval at all.
I realize there's a couple of solutions already, but thought I'd show one that has a tad more than just "do this". I tend to learn by example, and thought I would extend the same practice. That being said, the demo is here but I'll try to explain as well.
// Here we assign the function to a variable that we can use as an argument to the
// setInterval method.
var work = function(){
// performing a very simple action for the sake of demo
$('#log').append('Executed.<br />');
};
// this is a variable that is essentially used to track if the interval is or is
// not already running. Before we start it, we check it. Before we end it, we also
// check it. Let's start off with it started though
var worker = setInterval(work, 5000);
// bind to the start button
$('#start').click(function(){
// Test: is the worker already running?
if (worker)
// Yes it is, don't try to call it again
$('#warn').text('Timer already running!');
else{
// no it's not, let's start it up using that function variable we declared
// earlier
worker = setInterval(work,3000);
$('#warn').text('Started!');
}
});
// bind to the stop button
$('#stop').click(function(){
// test: is the worker running?
if (!worker)
// no, so we can't stop it
$('#warn').text('Timer not running!');
else{
// yes it's working. Let's stop it and clear the variable.
clearInterval(worker);
worker = null;
$('#warn').text('Stopped.');
}
});
Unless myFunc returns a function I would do this (also use clearInterval in stead of clearTimeout):
var interval = setInterval(myFunc, 5000);
function buttonClick() {
clearInterval(interval);
// do some stuff
myFunc();
interval = setInterval(myFunc, 5000);
}
setInterval expects a function in its argument. You call a function by using myFunc(). so whatever is returned by myFunc was passed to setInterval which is probably not what you want.

Is there any way to call a function periodically in JavaScript?

Is there any way to call a function periodically in JavaScript?
The setInterval() method, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval().
var intervalId = setInterval(function() {
alert("Interval reached every 5s")
}, 5000);
// You can clear a periodic function by uncommenting:
// clearInterval(intervalId);
See more # setInterval() # MDN Web Docs
Please note that setInterval() is often not the best solution for periodic execution - It really depends on what javascript you're actually calling periodically.
eg. If you use setInterval() with a period of 1000ms and in the periodic function you make an ajax call that occasionally takes 2 seconds to return you will be making another ajax call before the first response gets back. This is usually undesirable.
Many libraries have periodic methods that protect against the pitfalls of using setInterval naively such as the Prototype example given by Nelson.
To achieve more robust periodic execution with a function that has a jQuery ajax call in it, consider something like this:
function myPeriodicMethod() {
$.ajax({
url: ...,
success: function(data) {
...
},
complete: function() {
// schedule the next request *only* when the current one is complete:
setTimeout(myPeriodicMethod, 1000);
}
});
}
// schedule the first invocation:
setTimeout(myPeriodicMethod, 1000);
Another approach is to use setTimeout but track elapsed time in a variable and then set the timeout delay on each invocation dynamically to execute a function as close to the desired interval as possible but never faster than you can get responses back.
Everyone has a setTimeout/setInterval solution already. I think that it is important to note that you can pass functions to setInterval, not just strings. Its actually probably a little "safer" to pass real functions instead of strings that will be "evaled" to those functions.
// example 1
function test() {
alert('called');
}
var interval = setInterval(test, 10000);
Or:
// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);
Old question but..
I also needed a periodical task runner and wrote TaskTimer. This is also useful when you need to run multiple tasks on different intervals.
// Timer with 1000ms (1 second) base interval resolution.
const timer = new TaskTimer(1000);
// Add task(s) based on tick intervals.
timer.add({
id: 'job1', // unique id of the task
tickInterval: 5, // run every 5 ticks (5 x interval = 5000 ms)
totalRuns: 10, // run 10 times only. (set to 0 for unlimited times)
callback(task) {
// code to be executed on each run
console.log(task.id + ' task has run ' + task.currentRuns + ' times.');
}
});
// Start the timer
timer.start();
TaskTimer works both in browser and Node. See documentation for all features.
You will want to have a look at setInterval() and setTimeout().
Here is a decent tutorial article.
yes - take a look at setInterval and setTimeout for executing code at certain times. setInterval would be the one to use to execute code periodically.
See a demo and answer here for usage
Since you want the function to be executed periodically, use setInterval
function test() {
alert('called!');
}
var id = setInterval('test();', 10000); //call test every 10 seconds.
function stop() { // call this to stop your interval.
clearInterval(id);
}
The native way is indeed setInterval()/clearInterval(), but if you are already using the Prototype library you can take advantage of PeriodicalExecutor:
new PeriodicalUpdator(myEvent, seconds);
This prevents overlapping calls. From http://www.prototypejs.org/api/periodicalExecuter:
"it shields you against multiple parallel executions of the callback function, should it take longer than the given interval to execute (it maintains an internal “running” flag, which is shielded against exceptions in the callback function). This is especially useful if you use one to interact with the user at given intervals (e.g. use a prompt or confirm call): this will avoid multiple message boxes all waiting to be actioned."

Categories

Resources