Reputation: 2021
I am trying to understand callbacks via setTimeout
function.
I have two sets of code :
for (var i = 1; i <= 10; i++) {
(function(callback,i){
setTimeout(function(){
callback(i)
}, 0);
})(function(val){console.log(val)},i);
It works fine printing 1,2,3,.... 10
But when i am trying to abstract setTimeout
's callback function as :
for (var i = 1; i <= 10; i++) {
(function(callback,i){
setTimeout(func, 0);
})(function(val){console.log(val)},i);
}
function func(){
callback(i)
}
It gives me error stating
Uncaught ReferenceError: callback is not defined
I know there is some issue with lexical scoping of declaration of that func function. But not able to comprehend the reason. Please do help me understand this.
Upvotes: 1
Views: 115
Reputation: 15290
In func
you don't have reference to callback
that you declared in your IIFE.So,it start looking in current scope which is your func
scope.then it try to find in global scope,it also not defined there.Finally it throws an error
You need to pass the refarence to this callback parateter refering the function to get rid of this error.
for (var i = 1; i <= 10; i++) {
(function(callback,i){
setTimeout(func.bind(null,callback,i), 0);
})(function(val){console.log(val)},i);
}
function func(callback,i){
callback(i)
}
Upvotes: 1
Reputation: 67217
It is throwing reference error because, the function func
it has a scope where there is no declaration for callback
. You can fix it by passing the callback as a parameter to func
.
for (var i = 1; i <= 10; i++) {
(function(callback, i) {
setTimeout(func, 0, callback.bind(null, i)); //Pass the callback here as a parameter to func.
//(setTimeout can pass its >2 parameter as
//its callback parameter)
})(function(val) {
console.log(val)
}, i);
}
function func(callback) { //receive the callback here and use it.
callback();
}
Upvotes: 2
Reputation: 1
callback
is not defined within func
. You can pass func
as parameter to IIFE, use Function.prototype.bind()
to pass i
to callback
: func
for (var i = 1; i <= 10; i++) {
(function(callback, i) {
setTimeout(callback.bind(null, i), 0);
})(func, i);
}
function func(val) {
console.log(val)
}
Upvotes: 2