Is self-calling functions in Javascript harmful? - javascript

I have a Javascript function that is calling itself for purpose of refreshing notification bar. My function is like:
function refreshLoop() {
refresh();
setTimeout("refreshLoop();", 10000);
}
My question is that if I use that function like this, will be there any harm -programming error-. I am asking this question because you see refreshLoop() function never ends.
Should I use it like this or do you have any other ideas?
Thanks

This construct is frequent and fine (especially if a conditional call of setTimeout makes it hard to use setInterval), but it's not written as you did. Don't eval code when you can directly pass the function. Use this :
function refreshLoop() {
refresh();
setTimeout(refreshLoop, 10000);
}

You can end the timeout loop by removing the timeout like that:
var timeout;
function refreshLoop() {
refresh();
timeout = setTimeout(refreshLoop, 1000);
}
refreshLoop()
// later on
clearTimeout(timeout)

I don't see anything wrong with it, but you could lose the eval "refreshLoop();"
function refreshLoop() {
refresh();
setTimeout(refreshLoop, 10000);
}

Related

Auto-execute parenthesis creates problems with setInterval?

setInterval(function () {myFunction()}, 1000);
(function myFunction() {
...
})();
The parenthesis around the function make it run automatically. However, it causes problems with setting the interval for that function. Is there any way to fix this? Or, perhaps, a better way to make functions run automatically?
Thank you in advance.
You've created an IIFE, and the name of the function is only accessible inside the function, to the interval call, myFunction is not defined.
If you want to create a function, and then run it right away and in an interval, you just do that
function myFunction() { // make pretty function
...
};
setInterval(function () {
myFunction(); // make pretty function run each second
}, 1000);
myFunction(); // make pretty function run now

Javascript Callback functions vs just calling functions

So i don't really understand the point of "callback".
Here is an example of callback:
function sayBye(){
alert("Bye!");
}
function saySeeYou(){
alert("See you!");
}
function sayHello(name,myfunc){
alert("Hello");
myfunc;
}
sayHello("Max",saySeeYou());
Whats the point of passing in a function when you can just call the function? like this code does the exact same:
function sayBye(){
alert("Bye!");
}
function saySeeYou(){
alert("See you!");
}
function sayHello(name){
alert("Hello");
saySeeYou();
}
sayHello("Max");
Whats the point of passing in a function when you can just call the function?
Usually, callbacks Javascript are used in Javascript for code that you want to run in the future. The simplest example is setTimeout: if you call the callback now then the code runs immedieately instead of after 500 ms.
//prints with a delay
console.log("Hello");
setTimeout(function(){
console.log("Bye");
}, 500);
//no delay this time
console.log("Hello");
console.log("Bye");
Of course, it would be really neat if we could write something along the lines of
//fake Javascript:
console.log("Hello");
wait(500);
console.log("Bye");
But sadly Javascript doesnt let you do that. Javascript is strictly single-threaded so the only way to code the wait function would be to pause the execution of any scripts in the page for 500 ms, which would "freeze" things in an unresponsive state. Because of this, operations that take a long time to complete, like timeouts or AJAX requests usually use callbacks to signal when they are done instead of blocking execution and then returning when done.
By the way, when passing callbacks you should only pass the function name. If you add the parenthesis you are instead calling the function and passing its return value instead:
//When you write
foo(10, mycallback());
//You are actually doing
var res = mycallback();
foo(10, res);
//which will run things in the wrong order
Your code is not correct as Felix Kling already pointed out. Besides this, passing a function instead of calling one directly allows you to insert different behavior, your code is more decoupled and flexible. Here an example:
function sayBye(){
alert("Bye!");
}
function saySeeYou(){
alert("See you!");
}
function sayHello(name,myfunc){
alert("Hello");
if (myfunc) {
myfunc();
}
}
sayHello("Max",saySeeYou);
// I'm inserting a different behavior. Now instead of displayng "See you!"
// will show "Bye!".
sayHello("Max",sayBye);
You are doing it wrong, you should do like bellow
Don't call the function just pass the function as callback
use this
sayHello("Max",saySeeYou); //here the second parameter is function
instead of
sayHello("Max",saySeeYou());//This will put the result of saySeeYou as second parameter
in say hello call the functiom
function sayHello(name,myfunc){
console.log("Hello");
myfunc();
}

Can javascript's 'setInterval' be configured to trigger immediately, and with an interval?

If I want to trigger an event regularly I use something like (coffeescript):
setInterval (() => myFunction()), 300000
But often I want myFunction called immediately, AND regular intervals thereafter. At present I do this by calling both setTimeout and setInterval, e.g.,
setTimeout (() => myFunction()), 0
setInterval (() => myFunction()), 300000
or
myFunction()
setInterval (() => myFunction()), 300000
Can setInterval be used to do this in one step?
If your function is able to return itself, then yes.
function myFunction() {
// do some work
return myFunction;
}
setInterval(myFunction(), 300000);
I'll let you translate to CS.
So now you're invoking the function instead of passing it to setInterval(). The function runs, and returns itself, which is received by setInterval() and invoked as you'd expect.
I don't know CS, but it looks like you may be passing an anonymous function that invokes your function.
If so, I'm not sure why you're doing that, but it does guarantee that you can take this approach since you don't need to care about the return value of the original.
function myFunction() {
// do some work
}
setInterval(function() {
myFunction();
return myFunction;
}(), 300000);
If there's more work to do in the anonymous function that should run at every interval, then give the function a name and change return myFunction; to return callback;.
function myFunction() {
// do some work
}
setInterval(function callback() {
myFunction();
// some other work
return callback;
}(), 300000);
You can create a custom version of setInterval() that calls the specified function once at the start and then at intervals.
// custom version
window.setIntervalCustom = function(_callback, _delay) {
_callback(); // call once
return window.setInterval(_callback, _delay); // at intervals
};
// this will print 1 once at the start and then at intervals of 1000ms
setIntervalCustom(function() { console.log('1'); }, 1000);
Note: The custom function has been renamed above to avoid any conflict issues with other libs/code thiat might be using the original setInterval()

Repeat function execution start problem

I repeat execution of function on every second like
setInterval(function(){ /* some code */},1000};
What to change so function would be executed first time immediately and then repeats on every 1 second, any parameter I missed ?
You can use a self-executing function:
(function Fos () {
//do your stuff here
setTimeout(Fos, 1000);
})();
This function will invoke itself, and then set a timeout to run itself again in a second.
EDIT: Just one more note. In my example I used a named function expression (I used the name "Fos"), which allows us to reference the function itself inside the function. Some other examples use arguments.callee, which does not even work in ECMAScript 5 Strict mode, and generally not a recommended practice nowadays. You can read more about it in the SO question Why was the arguments.callee.caller property deprecated in JavaScript?
You might want to declare the function, run it and after that set the interval:
function something() { /* ... */ } // declare function
something(); // run it now immediately (once)
setInterval(something, 1000); // set an interval to run each second from now on
nope. the best you can do is:
var worker = function() { /* code */ }
worker();
setInterval(worker, 1000)
You could use a slightly different pattern like this:
(function() {
/*code*/
setTimeout(arguments.callee, 1000);
})()
Note that arguments.callee isn't allowed in strict mode, so then you could do something like:
var worker = function() {
/*code*/
setTimeout(worker, 1000);
}
worker();
The latter two code examples will create a function that will call itself 1000 milliseconds after executing. See this link for more details on the differences (advantages/disadvantages) between using setInterval() and setTimeout() chaining.
An additional solution to the ones already suggested is to return the anonymous function in its declaration, and calling the function immediately after it has been declared.
This way you don't have to use an additional variable and you can still use the interval ID returned by setInterval, which means that you can abort it using clearInterval later.
Eg. http://jsfiddle.net/mqchen/NRQBK/
setInterval((function() {
document.write("Hello "); // stuff your function should do
return arguments.callee;
})(), 1000);

window.setInterval from inside an object

I'm currently having an issue where I have a javascript object that is trying to use setInterval to call a private function inside of itself. However, it can't find the object when I try to call it. I have a feeling that it's because window.setInterval is trying to call into the object from outside but doesn't have a reference to the object. FWIW - I can't get it to work with the function being public either.
The basic requirement is that I may need to have multiple instances of this object to track multiple uploads that are occurring at once. If you have a better design than the current one or can get the current one working then I'm all ears.
The following code is meant to continuously ping a web service to get the status of my file upload:
var FileUploader = function(uploadKey) {
var intervalId;
var UpdateProgress = function() {
$.get('someWebService', {},
function(json) {
alert('success');
});
};
return {
BeginTrackProgress: function() {
intervalId = window.setInterval('UpdateProgress()', 1500);
},
EndTrackProgress: function() {
clearInterval(intervalId);
}
};
};
This is how it is being called:
var fileUploader = new FileUploader('myFileKey');
fileUploader.BeginTrackProgress();
Use this
intervalId = window.setInterval(UpdateProgress, 1500);
setInterval with a literal argument will eval this in the global scope where UpdateProgress is not accessible.
Because it is an eval expression, it does not have access to the scope that setInterval is created in. Try:
intervalId = window.setInterval(UpdateProgress, 1500)
It is generally good practice to avoid eval style expressions wherever possible. For instance, if you wanted to call several functions from the same timer, you would use an anonymous function instead of a string.
window.setInterval(function () {
function1();
function2();
}, 1500)
See also
Why is using javascript eval() a bad idea?
Anonymous function - Wikipedia
+1 to Andy E's head (I can't upvote yet, doh!)
Another gotcha that could get you is if you use this from within the called function.
Then doing exactly what Andy has with this addition should get you by.
var that = this;
window.setInterval(function() {
function1.apply(that);
function2.apply(that);
}, 1500);

Categories