Calling the setTimeout Function recursively and passing an anonymous function - javascript

I am confused on the difference between this syntax:
var timerId;
function clockStart(){
// debugger;
if(timerId){
return;
}
update();
// THIS LINE BELOW *********************************************
var timerId = setTimeout(function(){clockStart()}, 1000);
}
function clockStop(){
timerId = null;
}
function update(){
var date = new Date();
var hours = date.getHours();
var minutes = date.getMinutes();
var seconds = date.getSeconds();
if(hours < 10) {
hours = '0'+hours;
}
document.getElementById('hour').innerHTML = hours;
if(minutes < 10){
minutes = 0+minutes;
}
document.getElementById('min').innerHTML = minutes;
if(seconds < 10){
seconds = '0' + seconds;
}
document.getElementById('sec').innerHTML = seconds;
}
I provided both functions being called but the main part of this function I do not understand is why I need to pass an anonymous function to call my clockStart() function.
My function works when I use this syntax:
var timerId = setTimeout(function(){clockStart()}, 1000);
But it doesn't work when I use:
var timerId = setTimeout(clockStart(), 1000);
I have been working a while on these two functions and I honestly stumbled upon this by accident. I really don't see what the anonymous function is doing besides invoking my clockStart function. But in my opinion, my clockStart() function should be invoked every second(1000ms) since it is calling itself, so why does it need an anonymous function to invoke it? Shouldn't it be invoking itself?
If you would like to see this digital 'clock's' full code please checkout my codepen link.

This line:
var timerId = setTimeout(clockStart(), 1000);
is calling clockStart() immediately and passing the return result from that function to setTimeout(). Since the function doesn't return anything, you're effectively doing this:
clockStart();
var timerId = setTimeout(undefined, 1000);
which obviously doesn't do what you want.
You can use this instead:
var timerId = setTimeout(clockStart, 1000);
In this case, you want to pass a function reference to setTimeout() which means you do not include the parens. When you include the parens, that means to execute it NOW. When you just pass the name of the function, that is just a reference to the function (think of it like a handle) by which setTimeout() can call it later. That's what you want.
When you do this:
var timerId = setTimeout(function(){clockStart()}, 1000)
you're just defining an anonymous function and passing a reference to that anonymous function to to setTimeout() which works fine, but is not necessary in this case since you can just pass the clockStart name as in my third code example above.
Since you asked about how a function can call something later, I'll show you a simple example. Here's a function that takes a starting value, an ending value, an increment and a callback function. This will call the callback and pass it the value that it's incrementing until the value exceeds the end value.
// define an increment function that will call a callback
// multiple times based on the start, end and increment arguments
function eachIncrement(start, end, increment, callback) {
// the function argument named callback contains
// a function reference
var val = start;
while (val <= end) {
// execute the function reference and
// pass it the current val
callback(val);
val += increment;
}
}
// define a function that we want to be called later
function processValues(num) {
// this will get called multiple times with
// values 1, 4, 7, 10
}
// set up the increment parameters and pass a function reference
eachIncrement(1, 10, 3, processValues);

Related

javascript function does not work with passing a parameter [duplicate]

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!

Event listener for detecting hour

I'm doing a simple script for detecting when it's 12 o'clock, that it shows a certain div, if not that it remains hidden. So the general idea is this:
function displayDiv() {
d = new Date();
if(12 === d.getHours()){
idMain.style.display = 'block';
} else {
idMain.style.display = 'none';
}
}
But I want that in an event listener so when it's that hour it automatically displays the div or hides it. Something like:
document.addEventListener(d.getHour() === 12, displayDiv);
Or something like that but I don't know how to establish the parameters to get the desired response or for it to work.
Thanks
You can use a setInterval to run the function every minute (60000 milliseconds).
function displayDiv() {
d = new Date();
if(12 === d.getHours()){
idMain.style.display = 'block';
} else {
idMain.style.display = 'none';
}
}
setInterval(displayDiv, 60000);
I completely agree with Hev1 solution of using the setInterval (use his implementation). Here is some additional information though:
setInterval takes 2 arguments. The first argument is the callback function which you want to execute at a specific time interval. And the second argument is the amount of miliseconds you want the function to execute.
Also I want to point out if you ever are in need of clearing the interval there is also a function for this call clearInterval. You have to store the interval in an variable for this, here is an example:
const myInterval = setInterval(increase, 1000);
let index = 5;
function increase() {
if (index === 0) {
clear();
} else {
console.log(index);
index--;
}
}
function clear() {
clearInterval(myInterval);
console.log('interval cleared');
}
After the interval is stored in a variable the clear() method gets called when the interval reaches 0. In the clear function clearInterval is called to remove the interval.
We can put the if condition using following current time values.
var dates = new Date();
var hours = dates.getHours(); var minutes = dates.getMinutes();

setInterval call to function with other arg

I have a function called "showCustomer" that get number between 1-5 and return something.
I want to use setInterval, to run this function every 5 second but with another number.
Its not working, i don't understand why its not working to me. here is the code.
setInterval(function () {
var i = 1;
showCustomer(i);
i++;
}, 5000);
Just move the declaration of variable i before the setInterval() call:
var i = 1;
setInterval(function () {
showCustomer(i);
i++;
}, 5000);
The anonymous function you've set as a callback for setInterval gets called every 5 seconds in your code. In every call, you're setting i to 1 which resets it every time.
Moving i outside the setInterval callback makes it persist the the current value.
Every time you use var, you redeclare the value of that variable. So you only should declare the counter one time.
Every time that the browser calls the callback showCustomer the if statement evaluates if the browser should make a new call.
clearInvertal() it's the method to stop the setInterval() method.
var id = 1;
var show5times = window.setInterval(showCustomer, 5000);
function showCustomer() {
alert(id);
id++;
if(id > 5) {
window.clearInterval(show5times);
}
}

Javascript setInterval() - Why does my "input" parameter changes to undefined?

I've been working on the below code but couldn't figure out that why does my function parameter "input" changes to undefined after 1 second?
Here is the code:
<div id="new_time"></div>
<div id='input'></div>
<script>
var mins = 0;
var hrs = 0;
var secs = 0;
var test = 0;
function time_calc(input)
{
document.getElementById('new_time').innerHTML = secs++;
document.getElementById('input').innerHTML = input;
if (secs>59)
{
mins += 1;
secs = 0;
if (mins>59)
{
hrs += 1;
mins = 0;
}
}
while (secs == input)
{
clearInterval(secs_inc);
}
document.getElementById('new_time').innerHTML = hrs + ":" + mins + ":" + secs;
}
time_calc(20);
var secs_inc = setInterval(time_calc, 1000);
</script>
What do you expect it to be? You call the function time_calc after one second using setInterval. But it is called just like that, without arguments. So the argument input doesn't get a value, making it undefined.
When you try to assign it to the element, it is translated to the text undefined.
One way to solve this, is wrapping it in a function. This can be an anonymous function:
var secs_inc = setInterval(function(){timecalc(20)}, 1000);
Dressed down example:
function time_calc(input) {
document.getElementById('input').innerText = input;
}
setInterval(function(){time_calc(20)}, 3000);
<span id="input">Wait for it....</span>
If you call setInterval(time_calc(20), 1000), you actually call the function time_calc(), and pass the result to setInterval.
But you must not call it. You need to pass the function itself to setInterval, so setInterval can call it later. That's why in your original snippet you passed time_calc without parentheses. It's just the function without the call.
What I did, is wrap the call to time_calc(20) in another (anonymous) function that also doesn't have arguments. And now it's the anonymous wrapper function that is called by setInterval, which in turn calls time_calc with an argument.
It doesn't have to be an anonymous function by the way. I think for this case it's the easiest solution, but declaring an actual named function as #sudhAnsu63 demonstrated in his answer should work too.
Try calling your function like this.
var secs_inc = setInterval(new function(){
time_calc(20);}, 1000);
Or
function Calltime()
{
time_calc(20);
}
var secs_inc = setInterval(Calltime, 1000);

setInterval(setTimeout) function for given invokes javascript

I need to invoke some function given number of times through given delays. How should I do - declare variable for timer and pass it to invoking function for stopping timer in some moment or in loop (n times) invoke setTimeout once ( or some another approach to skeep delay time once) or other.Thanks.
edit to fix syntax eror
var timerID = null;
var n = 5;
this.timerID = setInterval(function(){
funcToInvoke(n,timerID){
if(invokeNumber == n){
clearInterval(timerID);
return;
}
else { do something}
}
},delay)
Yes, the approach is common and better than calling setTimeout in a loop (with a fixed number of times). It is more performant than that and also more flexible, because the interval will be stopped dynamically (might check for a future condition).
However, your code is a bit messy. Fixed:
// Assuming we a have
// n
// delay
// funcToInvoke
// and execute in context of some object
var that = this,
numberOfInvokes = 0;
this.timer = setInterval(function() {
// "this" points to the global object
if (numberOfInvokes == n)
clearInterval(that.timer);
else
funcToInvoke(numberOfInvokes);
numberOfInvokes++;
}, delay);
Your current method has a syntax problem, you can't have a function parameter like this.timerID). In fact, you should remove the whole funcToInvoke declaration, and declare n and timerID as local variables, so they will be available to the closure. Like this:
// Don't forget to define n here!
var n = 5;
// Change timerID to local var instead of property
var timerID = null;
timerID = setInterval(function(){
if(invokeNumber == n){
clearInterval(timerID);
return;
} else {
//do something
}
// You can setTimeout again anywhere in this function if needed
}, delay);
If you want an approximate delay, setInterval is probably ok. If you want a more precise interval, then repeated calls to setTimeout are better as you can adjust the length of time to the next call based on the time since the last call.
E.g. for a clock ticking every second, you can do repeated calls to setTimeout, setting the lag to just after the next full second.

Categories

Resources