How can an inner function call a parent function after it has expired?
setTimeout(main, 2000);
function main(){
/* .... code */
setTimeout(console.log("hello after 5 seconds"), 5000);
}
The intended action is to print hello after 5 seconds in 5 seconds (7 total); with the above code it prints it in 2 seconds.
You need to pass setTimeout function references. With setTimeout(console.log("hello after 5 seconds"), 5000);, you call console.log immediately. Any time you write () after a function name, you're invoking it.
console.log returns undefined, which is what is passed to setTimeout. It just ignores the undefined value and does nothing. (And it doesn't throw any errors.)
If you need to pass parameters to your callback function, there are a few different ways to go.
Anonymous function:
setTimeout(function() {
console.log('...');
}, 5000);
Return a function:
function logger(msg) {
return function() {
console.log(msg);
}
}
// now, whenever you need to do a setTimeout...
setTimeout(logger('...'), 5000);
This works because invoking logger simply returns a new anonymous function that closes over msg. The returned function is what is actually passed to setTimeout, and when the callback is fired, it has access to msg via the closure.
I think I understood what you want. Take a look:
var main = function(){
console.log("foo");
var function1 = function( string ) {
console.log("function1: " + string);
};
var function2 = function() {
console.log( "hadouken!" );
};
// you will need to use a closure to call the function
// that you want with parameters
// if you dont have parameters, just pass the function itself
setTimeout(function(){ function1("bar") }, 5000);
setTimeout(function2, 6000);
}
setTimeout(main, 2000);
Or:
function main(){
console.log("foo");
function function1( string ) {
console.log("function1: " + string);
};
function function2() {
console.log( "hadouken!" );
};
// you will need to use a closure to call the function
// that you want with parameters
// if you dont have parameters, just pass the function itself
setTimeout(function(){ function1("bar") }, 5000);
setTimeout(function2, 6000);
}
setTimeout(main, 2000);
I usually prefer the first sintax.
jsFiddle: http://jsfiddle.net/davidbuzatto/65VsV/
It works! You miss word function.
setTimeout(main, 1000);
function main() {
function function1 () { alert(1); };
setTimeout(function1, 1000);
}
Related
I have two very basic functions in Javascript
function def(){
console.log("DEF")
}
function abc(){
setTimeout(function(){
console.log("ABC")
}, 1000)
def();
}
abc();
The above functions prints DEF and then ABC. I want to print them in order e.g. ABC and then DEF.
I have basic idea about callback but I am not getting as how to convert above functions to callback function to get the desired output :)
In JavaScript, functions are first-class members so you can pass them as parameters into other function just as you would any other object:
function def(){
console.log("DEF")
}
function abc(){
setTimeout(function(){
console.log("ABC")
}, 1000)
}
function withCallbacks(...callbacks) {
callbacks.forEach(callback => callback());
}
withCallbacks(abc, def); // prints DEF, ABC
According to my opinion the answer by #Mateusz is unnecessarily complicated.
If you want to send a callback to any function you have to send it as a parameter to that function.
// Function you want to send as a callback
function def(){
console.log("DEF")
}
// Function in which you want to call this callback
function abc(callback){
setTimeout(function(){
// Log ABC to the console
console.log("ABC");
// Call the callback function after the ABC has been logged
callback();
}, 1000);
}
// Call the function and pass your callback as parameter
abc(def);
I'm assigning to a variable, a function that uses setInterval, but I don't want the function to run until I call it. However, the function is running from just the assignment statement.
sessionClock = setInterval(function() {
console.log("Hi")
}, 1000)
I have also tried like this:
sayHi = function() {
console.log("Hi");
}
var sayHiStarter = setInterval(sayHi, 1000);
Both of these initiate the function and will log "Hi" to the console.
Why is it running on assignment? And what can do I do fix this?
If you only want to bind a function to setInterval, but call it later, you can use bind:
var sessionClock = setInterval.bind(null, function() {
console.log("Hi")
}, 1000);
//... later
var myInterval = sessionClock(); // start the timer
// ... later if you need to clear it
clearInterval(myInterval);
In principle, bind returns a new function that calls your original function (in this case, setInterval) with predefined arguments. So when you call sessionClock, that returned function is called. There a other aspects to bind, but they don't seem to apply in this context.
The call to setInterval does not return a function, but an identification for the created interval. This id is used to remove the interval when you don't want it to execute anymore:
sessionClock = setInterval(function() {
console.log("Hi")
}, 1000)
...
clearInterval(sessionclock);
What you want is something like this:
sessionClock = function () {
return setInterval(function() {
console.log("Hi")
},
1000);
}
//When needed
var intervalId=sessionClock();
I have a code similar to the below.
function test(){
return function(){
setInterval(//Another Function Reference // ,1000);
}
}
I am calling test()();
I see the above code not working. Could someone please explain me why?
There is no closure in your code1. test returns a function object, but that [function] is not executed. In the snippet, 3 closures are used in the inner function, the returned function object is assigned to a variable, and that is executed. The advantage of returning a function object is that you can assign it to different values and execute them separately.
1 Earlier version of the question mentioned 'closure not working'
// startInterval: interval 1 second, message: 'Hello' (default)
var startInterval = test(null, 1000);
// anotherInterval: interval 5 seconds, message: ''Hello to you too''
var anotherInterval = test('<i>Hello to you too</i>', 5000);
// execute the function objects
startInterval();
anotherInterval();
// [hithere], [time] and [result] are closed over
function test(hithere, time){
hithere = hithere || 'Hello';
time = time || 1000;
var result = document.querySelector('#result');
return function(){
setInterval(function(){
result.innerHTML += hithere+'<br>';
},time || 1000);
}
}
<div id="result">Greetings!<hr></div>
function test(){
return function(){
setInterval(function(){
alert("Hello");
},1000);
}
}
var hello = test();
hello();
It seems to be working fine. Remember that if you call test(), you just get the function back, but you haven't run it. To run it, you need to call the resulting function. You can do this by either:
test()();
Or:
var myFunction = test();
myFunction();
It is working for me... you are returning a function so you will need to invoke this:
http://jsfiddle.net/97hzj2je/
function test(){
return function(){
setInterval(function(){
alert("Hello");
},1000);
}
}
test()();
I assume you are wanting test() to be a self invoking function so the return function is set once so instead do:
http://jsfiddle.net/LL24g8z2/
var test = (function(){
return function(){
setInterval(function(){
alert("Hello");
},1000);
}
})();
test();
bind your inner function to the context, the problem is that when the set interval is finally being executed it is in the global scope and not in the one that you called it from. Can be fixed like this:
function test(){
return function(){
setInterval(/*Another Function Reference */ ,1000);
}.bind(this)
}
I have two asynchronous objects fn1 and fn2 and sometimes I want to run them synchronously.
For simplicity I wrote the code in this way:
var fn1 = function () {
setTimeout(function () {
console.log("fn1");
},200);
};
var fn2 = function () {
setTimeout(function () {
console.log("fn2");
},100);
};
fn1();
fn2();
but let's suppose is not possible to modify the fn1 and fn2 object.
What is the best way to run fn2 only when fn1 has finished to be executed?
If you want to execute f1() when f2() has finished, use the method as described and shown below.
Create a poller function, which checks for variable/property changes created by method fn2. Example:
function fn1(){/*...*/}
function fn2(){
//Lots of code, including:
window.someDynamicVar = "SPECIAL_token"; //Unique, only defined by this func
}
(function(){//Anonymous wrapper, don't leak variables
var timer = window.setInterval(function(){
//check whether an unique environment change has been made by fn2():
if(window.someDynamicvar == "SPECIAL_token"){
clearInterval(timer); //Clear the poller
fn1(); //Call fn1
}
}, 200); //Poller interval 200ms
})();
The concept behind this code is that the fn2() function changes variables during/after execution, which can be read. When such a change has been detected, the poller is cleared, and fn1() is executed.
"...let's suppose is not possible to modify the fn1 and fn2 object."
Without modification, they will behave as asynchronous functions are meant to behave; they will run asynchronously.
If you have foreknowledge of the duration in the first function, you could delay the execution of the second by the same duration.
f1();
setTimeout(f2,200);
You should use a callback function.
http://recurial.com/programming/understanding-callback-functions-in-javascript/
var fn2 = function (myCallback) {
setTimeout(function () {
console.log("fn2");
myCallback();
},100); };
In the general case, there isn't a pretty way. Are you sure you can't change teh functions so they receive continuation functions to call when they are done?
function f1(continuation){
setTimeout(function(){
console.log("f1");
continuation(); //kind of like a return...
}, 100);
}
function f2(continuation){
setTimeout(function(){
console.log("f2");
continuation();
}, 100);
}
f1(function(){
f2( function(){
console.log("this runs after f2 ends");
})
})
fn1 and fn2 are most certainly objects, contrary to what is said below (or above), but that's a different story. The easiest way to do what you want to, it to provide an optional callback parameter.
var fn1 = function (callback) {
setTimeout(function () {
console.log("fn1");
if (callback) callback();
},200);
};
var fn2 = function (callback) {
setTimeout(function () {
console.log("fn2");
if (callback) callback();
},100);
};
So instead of:
fn1();
fn2();
You would do:
fn1(fn2);
or to be explicit about it:
fn1(function() {
fn2();
});
fn1 and fn2 are not objects
Read up about setTimeout. Get fn1 to call fn2 when it is done
How can I use setTimeout if I want to return a value
$.each(pCodes, function(index, pCode) {
setTimeout(func(parm1), 2000);
});
function func(in)
{
var value = 999;
return value;
}
First of all, your call to setTimeout is wrong. You are calling the function func and then using the result in the setTimeout method. Your code is equivalent to:
$.each(pCodes, function(index, pCode) {
var temp = func(parm1);
setTimeout(temp, 2000);
});
As func returns 999, you will be doing setTimeout(999, 2000), which of course doesn't make sense. To call a function that takes a parameter from setTimeout you need a function that makes that function call:
$.each(pCodes, function(index, pCode) {
setTimeout(function() { func(parm1); }, 2000);
});
To handle the return value from func is a bit more complicated. As it's called later on, you have to handle the return value later on. Usually that is done with a callback method that is called when the return value is available:
var callback = function(value) {
// Here you can use the value.
};
$.each(pCodes, function(index, pCode) {
setTimeout(function() { func(parm1, callback); }, 2000);
});
function func(in, callback) {
var value = 999;
callback(value);
}
First of all, make sure you pass to setTimeout a function, in your example you passed undefined to it, as you func(param1) executes func directly. What you want is something like this:
setTimeout(function() { func(parm1); }, 2000);
And for 'returning' the value: Use some kind of callback function that is executed with the value when timeout expired. Like so:
function callback(value) {
// doSomethingWithNewValue
}
$.each(pCodes, function(index, pCode) {
setTimeout(function() { func(parm1, callback); }, 2000);
});
function func(in, callback)
{
var value = 999;
callback(value);
}
This is the general pattern used in such scenario (see event driven programming).
change it to :
var defValue;
$.each(pCodes, function(index, pCode) {
setTimeout(function(){defValue=func(parm1)}, 2000);
});
this way you can use the defValue in your function to access the returned value
It's pretty ugly, but you can use output parameters, since js objects are pass by reference:
function a() {
var param1 = 42;
var result = {};
b(param1, result);
}
function b(val, output) {
something();
output.returned = 4;
}
Or, you can use a callback (the better option):
function a() {
var param1 = 42;
b(param1, function (newVal) {
something();
});
}
function b(val, callback) {
//something
callback(4);
}
By the way, your call to setTimeout is wrong. setTimeout receives a function as a first parameter, and a delay as a second - the first argument is still seen as regular javascript code, so it evaluates it, so your setTimeout call turns out to be like this:
setTimeout(999, 2000);
Since you're returning 999 from the function.
However, setTimeout can also receive a list of arguments after the second parameter, so it can be turned into this:
setTimeout(func, 2000, param1);