Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to pass variables into callback functions in Node.js

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.

like image 377
Justin Avatar asked Sep 28 '12 06:09

Justin


People also ask

How do you pass a variable in node JS?

You can have your module export a function and then call the function when you import, passing your variable as an argument. module. exports = function(myVar) { var myModule = { // has access to myVar ... }; return myModule; };

Can callbacks have parameters?

The print( ) function takes another function as a parameter and calls it inside. This is valid in JavaScript and we call it a “callback”. So a function that is passed to another function as a parameter is a callback function.

Which is faster callback or promise?

So from my findings i assure you ES6 promises are faster and recommended than old callbacks.


2 Answers

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));
}
like image 137
xdazz Avatar answered Oct 12 '22 20:10

xdazz


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
}
like image 37
Tharabas Avatar answered Oct 12 '22 19:10

Tharabas