I've been wondering, is there a better way to pass variables into callback functions in node.js other than using bind()
.
Here is an example:
var fs = require('fs');
for(var i = 0; i < 100; i++) {
fs.writeFile(i + ".txt", i, function(error) {
fs.stat(this.i + ".txt", function() {
fs.rename(this.i + ".txt", this.i + ".new.txt", function() {
console.log("[" + this.i + "] Done...");
}.bind({ i: this.i }));
}.bind({ i: this.i }));
}.bind({ i: i }));
}
Notice the bind()
methods all the way up, simply passing the value of i
.
Thanks.
Variables in JavaScript are valid for the whole function scope.
This means that you can define a variable x
((var x = ...
) and it is still accessible in all functions, you define within the same calling scope.
(For detailed information you might want to take a look at JavaScript Closures
The problem of your case is, that you manipulate your i
during the for loop
.
If simply access the i
in the callback functions, you'd recieve the first value that is no longer in the loop.
You can avoid that by calling a new function with the i
as argument, like this:
var fs = require('fs');
// still use your for-loop for the initial index
// but rename i to index to avoid confusion
for (var index = 0; index < 100; index++) {
// now build a function for the scoping
(function(i) {
// inside this function the i will not be modified
// as it is passed as an argument
fs.writeFile(i + ".txt", i, function(error) {
fs.stat(i + ".txt", function() {
fs.rename(i + ".txt", i + ".new.txt", function() {
console.log("[" + i + "] Done...");
});
});
});
})(index) // call it with index, that will be i inside the function
}
I would like to do with below:
var fs = require('fs');
var getWriteFileCallback = function(index) {
return function(error) {
fs.stat(index + '.txt', function() {
fs.rename(index + '.txt', index + '.new.txt', function() {
console.log("[" + index + "] Done...");
});
});
};
}
for(var i = 0; i < 100; i++) {
fs.writeFile(i + ".txt", i, getWriteFileCallback(i));
}