So i have a major function which triggers another function every 2 - 17 seconds but when I try to stop it with clearTimeout() it just goes on and completely ignores the clearTimeout().
So this is my major function:
var itemTimer;
var stopTimeout;
function major (){
var itemTime = Math.floor(Math.random() * 15000) + 2000;
itemTimer = setTimeout('items()', itemTime);
stopTimeout = setTimeout('major()',itemTime);
}
And this is my stop timeout function:
function stopTimer() {
clearTimeout(itemTimer);
clearTimeout(stopTimeout);
}
Thank you for helping
Your setTimeout() is being called incorrectly; you're invoking items() and major(). Instead, you need to pass them as functions to be invoked.
Don't pass the brackets to the parameters, and don't wrap the parameters in quote marks.
Instead of:
itemTimer = setTimeout('items()', itemTime);
stopTimeout = setTimeout('major()',itemTime);
You're looking for:
itemTimer = setTimeout(items, itemTime);
stopTimeout = setTimeout(major, itemTime);
Hope this helps! :)
I think your timeouts are stacking up. As soon as major gets called once, the variables itemTimer and stopTimeout get reassigned a new timeout reference. So there will be no way to clear the timeouts that were previously set. If this is the case it should be an easy fix though. Just call stopTimer as very first statement in major:
function major (){
stopTimer();
var itemTime = Math.floor(Math.random() * 15000) + 2000;
itemTimer = setTimeout('items()', itemTime);
stopTimeout = setTimeout('major()',itemTime);
}
Related
Please advise how to pass parameters into a function called using setInterval.
My example setInterval(funca(10,3), 500); is incorrect.
You need to create an anonymous function so the actual function isn't executed right away.
setInterval( function() { funca(10,3); }, 500 );
Add them as parameters to setInterval:
setInterval(funca, 500, 10, 3);
The syntax in your question uses eval, which is not recommended practice.
now with ES5, bind method Function prototype :
setInterval(funca.bind(null,10,3),500);
Reference here
setInterval(function(a,b,c){
console.log(a + b +c);
}, 500, 1,2,3);
//note the console will print 6
//here we are passing 1,2,3 for a,b,c arguments
// tested in node v 8.11 and chrome 69
You can pass the parameter(s) as a property of the function object, not as a parameter:
var f = this.someFunction; //use 'this' if called from class
f.parameter1 = obj;
f.parameter2 = this;
f.parameter3 = whatever;
setInterval(f, 1000);
Then in your function someFunction, you will have access to the parameters. This is particularly useful inside classes where the scope goes to the global space automatically and you lose references to the class that called setInterval to begin with. With this approach, "parameter2" in "someFunction", in the example above, will have the right scope.
setInterval(function,milliseconds,param1,param2,...)
Update: 2018 - use the "spread" operator
function repeater(param1, param2, param3){
alert(param1);
alert(param2);
alert(param3);
}
let input = [1,2,3];
setInterval(repeater,3000,...input);
You can use an anonymous function;
setInterval(function() { funca(10,3); },500);
By far the most practical answer is the one given by tvanfosson, all i can do is give you an updated version with ES6:
setInterval( ()=>{ funca(10,3); }, 500);
Quoting the arguments should be enough:
OK --> reloadIntervalID = window.setInterval( "reloadSeries('"+param2Pass+"')" , 5000)
KO --> reloadIntervalID = window.setInterval( "reloadSeries( "+param2Pass+" )" , 5000)
Note the single quote ' for each argument.
Tested with IE8, Chrome and FireFox
const designated = "1 jan 2021"
function countdown(designated_time){
const currentTime = new Date();
const future_time = new Date(designated_time);
console.log(future_time - currentTime);
}
countdown(designated);
setInterval(countdown, 1000, designated);
There are so many ways you can do this, me personally things this is clean and sweet.
The best solution to this answer is the next block of code:
setInterval(() => yourFunction(param1, param2), 1000);
I know this topic is so old but here is my solution about passing parameters in setInterval function.
Html:
var fiveMinutes = 60 * 2;
var display = document.querySelector('#timer');
startTimer(fiveMinutes, display);
JavaScript:
function startTimer(duration, display) {
var timer = duration,
minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
--timer; // put boolean value for minus values.
}, 1000);
}
This worked for me
let theNumber = document.getElementById('number');
let counter = 0;
function skills (counterInput, timer, element) {
setInterval(() => {
if(counterInput > counter) {
counter += 1;
element.textContent = `${counter} %`
}else {
clearInterval();
}
}, timer)
}
skills(70, 200, theNumber);
This works setInterval("foo(bar)",int,lang);.... Jon Kleiser lead me to the answer.
Another solution consists in pass your function like that (if you've got dynamics vars) :
setInterval('funca('+x+','+y+')',500);
You can use a library called underscore js. It gives a nice wrapper on the bind method and is a much cleaner syntax as well. Letting you execute the function in the specified scope.
http://underscorejs.org/#bind
_.bind(function, scope, *arguments)
That problem would be a nice demonstration for use of closures. The idea is that a function uses a variable of outer scope. Here is an example...
setInterval(makeClosure("Snowden"), 1000)
function makeClosure(name) {
var ret
ret = function(){
console.log("Hello, " + name);
}
return ret;
}
Function "makeClosure" returns another function, which has access to outer scope variable "name". So, basically, you need pass in whatever variables to "makeClosure" function and use them in function assigned to "ret" variable. Affectingly, setInterval will execute function assigned to "ret".
I have had the same problem with Vue app. In my case this solution is only works if anonymous function has declared as arrow function, regarding declaration at mounted () life circle hook.
Also, with IE Support > 9, you can pass more variables insider set interval that will be taken by you function. E.g:
function myFunc(arg1, arg2){};
setInterval(myFunc, 500, arg1, arg2);
Greetings!
I'm very new to coding (2 weeks experience) so please bare with my silly question about this code. Ultimately I want it to continuously run the function called "timer," which tells me how long it took to run the function called "add," display that result on my screen, and then update that results each time it runs.
function add(a,b){
return a + b;
}
function timer(){
var a = Math.floor(Math.random() * 101);
var b = Math.floor(Math.random() * 101);
var start = performance.now();
add();
var end = performance.now();
var duration = end - start;
return duration + ' milliseconds';
}
t = setInterval(timer,1000);
What this seems to do is return the number "1" and do nothing after.
Now when I replace
return duration + ' milliseconds'
with
console.log(duration + ' milliseconds')
it does what I want, except for the fact that the reason I don't want to use console.log is that it jumps to a new line when displaying the duration instead of replacing the previous line with the new duration. To clarify, I don't want a big list of durations that gets longer every time it runs, I just one one duration displayed, that gets updated and replaced each time it runs.
Thank you for your help!
setInterval is asynchronous so you will not get your return value this way. The number you are getting back is an ID for later when you want to clearInterval.
But let's say for fun setInterval did try to return your value.
You do t = setInterval(...) but when that happens your code inside of setInterval hasn't executed yet. It was just placed in the queue at that moment but the assignment of t = ... isn't waiting around.
maybe this could help https://code.tutsplus.com/tutorials/event-based-programming-what-async-has-over-sync--net-30027
You are setting t to the return value of setInterval()
The documentation says that setInterval() returns the following:
timeoutID ... a numeric, non-zero value which identifies the timer
It seems like what you actually want is to set the variable t somewhere inside timer(), so that when setInterval() calls it every 1000ms, it'll update t.
The function console.log appends to the console. So you will have to clear the console to achieve what you want.
If you are on chrome then call the
clear()
before
console.log() in timer function.
Hope it helps
If you want to be notified when setInterval is finished then you may need to use a promise:
function add(a,b) {
return a + b;
}
function timer(delayTime) {
return new Promise(
function(resolve) {
setInterval(
function() {
var a = Math.floor(Math.random() * 101);
var b = Math.floor(Math.random() * 101);
var start = performance.now();
add();
var end = performance.now();
var duration = end - start;
resolve(duration + ' milliseconds');
}, delayTime
);
}
);
}
timer(1000).then(
function(t) {
console.log(t);
}
);
When you say
display that result on my screen
I'm thinking you may be just looking to update an element's text. If you simply want to keep track of it, you will need to use a variable outside of the timer function and update that variable inside the function. As others have pointed, setInterval will return an ID for retrieving the interval later. For example, if you wanted to stop the timer, you would do clearInterval(t);
I created a code snippet that updates the duration on the screen every time:
function add(a,b){
return a + b;
}
function timer(){
var a = Math.floor(Math.random() * 101);
var b = Math.floor(Math.random() * 101);
var start = performance.now();
add();
var end = performance.now();
var duration = end - start;
document.getElementById('duration').innerHTML = duration + ' milliseconds';
}
t = setInterval(timer,1000);
Duration: <span id="duration"></span>
Also, take a look at this, since you are new to coding: How do I return the response from an asynchronous call?
I want a function I am writing to call itself automatically. I want to be able to parse the frequency at which it calls itself via the first time I parse it. It would then use that same value internally with the JS setTimeout() function to call itself repeatedly again at the same frequency.
So you can see what I have in the sample below:
function testFunction(refreshFrequ){
setTimeout(function() {
console.log("frequency: "+refreshFrequ);
testFunction(refreshFrequ);
}, refreshFrequ);
}
// run the 1st time
testFunction(5000);
The problem is that this doesn't work as from the second time it runs onwards the parsed timeout isn't evaluated. The console output gives a clue to what's going on here:
frequency: undefined
How would I get this working, nothing so far has helped.
Try Window setInterval() Method instead. Also see this answer and this answer for more information.
var autoInterval;
var elapsed = 0;
function myStartFunction(refreshFrequ) {
if (!autoInterval) {
autoInterval = setInterval(function() {
elapsed++;
document.getElementById("txt").innerHTML = refreshFrequ * elapsed + " elapsed.";
console.log("frequency interval: " + refreshFrequ + " x " + elapsed);
}, refreshFrequ);
}
}
function myStopFunction() {
if (autoInterval) {
clearInterval(autoInterval);
autoInterval = null;
elapsed = 0;
document.getElementById("txt").innerHTML = "Interval was reset.";
console.log("interval stopped");
}
}
myStartFunction(5000);
<p>The setInterval() method has started automatically.</p>
<button onclick="myStartFunction(1000)" title="Start with 1000 ms interval. Clicking this button while the event is active should not create a new interval instance.">Start</button> <button onclick="myStopFunction()" title="Click to stop and clear the interval instance.">Stop</button>
<p id="txt">0 elapsed.</p>
Edit: Although there was no mention of the potential duplicate function calls, the other answer should be taken into consideration, especially if the event can arbitrarily be executed. The if statement was imposed in order to prevent duplicate events from being stacked up against the original instance; otherwise, each additionally executed function would result in a unique instance, which could then further create unstoppable multiple events, so I must give credit where credit is due. Kudos to Tymek!
You might want to use setInterval instead.
var testFunction = (function () { // This will "build"/"enclose" our function
var handle = null; // ID of the interval
return function (freq) {
if (handle !== null) clearInterval(handle);
handle = setInterval(function() {
console.log("frequency: " + freq);
}, freq);
};
})();
With this if you re-initialize interval, you will not create another instance of it (having 2 functions ticking).
You can learn more about setInterval at: https://www.w3schools.com/jsref/met_win_setinterval.asp
and more about how JavaScript functions works at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
I've looked at many different solutions to this, none of which worked. I know it has something to do with setTimeout, but I don't know how to implement it properly.
function myfunction()
{
//the function
//wait for 1 second before it can be ran again
}
To clarify: I don't want to call the function at a regular interval, I want to be able to enforce a delay before the function can be called again.
var lastTime = 0;
function myFunction() {
var now = new Date().getTime(); // Time in milliseconds
if (now - lasttime < 1000) {
return;
} else {
lastTime = now;
}
// rest of function
}
You don't need to use setTimeout at all. The following is similar to other answers, but uses a closure to remember the last time the function ran rather than a global variable.
var myFunction = function() {
var lastTime = new Date();
return function() {
var now = new Date();
if ((now - lastTime) < 1000) return;
lastTime = now;
/* do stuff */
};
}());
I think the easiest solution would be to hold a boolean variable and reset it to true after a given delay.
fiddle
HTML
<button id="clickme">click me!</button>
JavaScript
var canGo = true,
delay = 1000; // one second
var myFunction = function () {
if (canGo) {
canGo = false;
// do whatever you want
alert("Hi!");
setTimeout(function () {
canGo = true;
}, delay)
} else {
alert("Can't go!");
}
}
$("#clickme").click(function(){
myFunction();
})
With this, you hold a boolean, canGo, and set it to true. If the function is run, it sets canGo to false and sets a setTimeout() for a time period of delay, in milliseconds. If you try to run the function again, it won't run and will, instead, alert("Can't go!"). This was just for demonstrative purposes; you don't need that part. After delay, canGo will be set to true, and you will be able to once more run the function.
var lastRan = 0;
var myFunction = function() {
var now = Date.now();
if(now-lastRan < 1000) {
return;
}
lastRan = now;
//rest of function
};
You may want to use throttle or debounce from underscore.js
http://underscorejs.org/#throttle
throttle_.throttle(function, wait, [options])
Creates and returns a
new, throttled version of the passed function, that, when invoked
repeatedly, will only actually call the original function at most once
per every wait milliseconds. Useful for rate-limiting events that
occur faster than you can keep up with.
By default, throttle will execute the function as soon as you call it
for the first time, and, if you call it again any number of times
during the wait period, as soon as that period is over. If you'd like
to disable the leading-edge call, pass {leading: false}, and if you'd
like to disable the execution on the trailing-edge, pass {trailing:
false}.
var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);
http://underscorejs.org/#debounce
debounce_.debounce(function, wait, [immediate])
Creates and returns a
new debounced version of the passed function which will postpone its
execution until after wait milliseconds have elapsed since the last
time it was invoked. Useful for implementing behavior that should only
happen after the input has stopped arriving. For example: rendering a
preview of a Markdown comment, recalculating a layout after the window
has stopped being resized, and so on.
Pass true for the immediate parameter to cause debounce to trigger the
function on the leading instead of the trailing edge of the wait
interval. Useful in circumstances like preventing accidental
double-clicks on a "submit" button from firing a second time.
var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);
If you just want to run your function again after a set time, you can use setTimeout and pass it the function to run and the delay period in milliseconds.
function myfunction() {
//the function
//run again in one second
setTimeout(myfunction, 1000);
}
Edited based on poster's comments:
var waiting = false;
var myfunction = function() {
if (!waiting) {
//Run some code
waiting = setTimeout(function() {
waiting = false;
}, 1000);
}
};
I used window.setInterval function. this function includes 3 arguments :
setInterval(code,millisec,lang)
I used that like this:
var counter = 1;
window.setInterval(function() {}, 1000 * ++counter);
but when first time set timer (second argument), is not changed and that act Like below code:
window.setInterval(function() {}, 1000);
please write correct code for change timer
Use window.setTimeout instead.
var delay = 1000;
function myTimer() {
// do whatever
window.setTimeout(myTimer, delay);
}
window.setTimeout(myTimer, delay);
You can manipulate delay in the body of your function.
Your problem is that javascript first execute '1000 * ++counter' once and then do not update the time interval.
You should try to use a timeout instead: https://developer.mozilla.org/en/DOM/window.setTimeout
And create a new time out with the new value every time your time out function is called.
Sounds like what you're after is not setInterval but rather setTimeout in a loop:
var counter = 1;
for (var i = 1; i <= 3; i++) {
window.setTimeout(function() {
alert("#" + counter);
counter++;
}, i * 1000);
}
This will execute three different "timers" one after the other.
Live test case: http://jsfiddle.net/86DRd/