Last active
September 28, 2015 17:41
-
-
Save shiffman/7b96d9951bb3865e7d38 to your computer and use it in GitHub Desktop.
Discussion of issues around callbacks for multiple elements in a loop. Using setTimeout() here for demonstration purposes. Actual scenario relates to examples here: https://github.com/shiffman/Programming-from-A-to-Z-F14/tree/master/week6_apis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// While this seems like the right idea | |
// This does not work at all! | |
// The loop will finish and i will be at 10 by | |
// the time the anonymous function is called | |
for (var i = 0; i < 100; i++) { | |
setTimeout(function() { | |
console.log(i); | |
}, 100*i); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Thanks to Sam Lavigne for suggesting this nice-looking methodology | |
for (var i = 0; i < 10; i++) { | |
// This will work by passing in a variable | |
// to a separate function | |
countit(i); | |
} | |
function countit(num) { | |
// This is a closure where | |
// the function declared here will retain | |
// num even after this has been completed | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures | |
setTimeout(function() { | |
console.log(s + num); | |
}, num * 1000); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Option #2 | |
// Function factory | |
function count(val) { | |
return function() { | |
console.log(val); | |
} | |
} | |
for(var i = 0; i < 100; i++) { | |
setTimeout(count(i), i*100); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Option #3 | |
// This is basically the same thing but using bind() | |
function count(val) { | |
console.log(val); | |
} | |
for(var i = 0; i < 100; i++) { | |
setTimeout(count.bind(null, i), i*100); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Option #4 | |
// Same as #2, but anonymous self-executing | |
function count(val) { | |
console.log(val); | |
} | |
for(var i = 0; i < 100; i++) { | |
setTimeout(function(val) { | |
return function() { | |
console.log(val); | |
} | |
}(i), i*100); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Thanks to Sam Lavigne for suggesting this nice-looking methodology | |
for (var i = 0; i < 10; i++) { | |
// This will work by passing in a variable | |
// to a separate function | |
countit(i); | |
} | |
function countit(num) { | |
// This is a closure where | |
// the function declared here will retain | |
// num even after this has been completed | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures | |
setTimeout(count, num * 1000); | |
function count() { | |
console.log(num); | |
} | |
} |
var t= new Array(100).map(function(e,i){
return setTimeout(function(){
console.log(i);
//at this point we can access both the timeout index e (for clearing) and the array index i
//also the array of all timeouts t
},100);
});
//something went wrong, we must cancel them
t.forEach(function(e,i){
clearTimeout(e);
});
For other async code that's not a timeout the array would be an array of promises you can pass to Promise.all() for example.
The most elegant solution I can think of is using 'let', but that's already been mentioned by ben. :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I don't see anything wrong with any of these. JS is like the jazz of the programming world. :)
Option #2 is actually a textbook example of a closure and is great for private functions. That's a proper engineering interview question. :) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures