Consider the following example:
var cb = function (t) {
console.log('callback -->' + t);
};
for(var i = 0; i<3; i++) {
console.log(i);
setTimeout(function(){
cb(i);
},1000);
}
Working example at jsfiddle
The output of this code snippet is:
0
1
2
callback ---> 3
callback ---> 3
callback ---> 3
Everything works as expected, for loop puts 3 callback calls into the event loop. By the end of the for loop i == 3 and when the callbacks get executed all of them print 3 because they contain the link to the i which is 3. How could this snippet be improved so when the callback gets executed it uses the actual value which was passed to it.
The output should be:
callback ---> 1
callback ---> 2
callback ---> 3
Thanks in advance.
A callback is just a function that's passed into another function, with the expectation that the callback will be called at the appropriate time. As we just saw, callbacks used to be the main way asynchronous functions were implemented in JavaScript.
The callback function, like any JavaScript function, will have access to the context where it was declared in. If the callback function is an inner function, it is a closure that is able to access variables in the outer function. As was shown above, closures can be used to maintain private state.
Await eliminates the use of callbacks in . then() and . catch(). In using async and await, async is prepended when returning a promise, await is prepended when calling a promise.
Callbacks that you call yourself are regular function calls, which are always synchronous. Certain native APIs (eg, AJAX, geolocation, Node. js disk or network APIs) are asynchronous and will execute their callbacks later in the event loop.
You could try .bind:
for(var i = 0; i<3; i++) {
console.log(i);
setTimeout(cb.bind(null, i),1000);
}
The demo.
The traditional way to handle this is to create a closure:
for(var i = 0; i<3; i++) {
console.log(i);
setTimeout((function(i){return function(){cb(i)}}(i)),1000);
}
A frequent question. Let's try to use some features of future of JS. I mean let. It creates local scope variable and you don't need to use a closure or another trick. But now it works only in FF (i'm using 20.0.1)
for(var i = 0; i<3; i++) {
console.log(i);
let a = i;
setTimeout(function(){
cb(a);
},1000);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With