LetMeSOThat4U LetMeSOThat4U - 17 days ago 4
Node.js Question

Javascript callbacks ordering and node

Per http://callbackhell.com/ I try to write callbacks (mostly for learning purposes before I proceed to promises) The Right Way(tm).

OK so I have this:

"use strict";

var fs = require('fs');

var readFileDone = function(err, data) {
if(err) return console.error(err);
console.log('read done');
writeFile(null, data);
};


var writeFile = function(err, data) {
if(err) return console.error(err);
var ws = fs.createWriteStream('/tmp/copy.txt')
ws.end(data, 'utf-8', writeFileDone);
};

var writeFileDone = function(err, data) {
console.log('writing file done');
};

fs.readFile('test_underscore1.js', readFileDone);


I run this using ST3's build system I defined for Javascript like so:

{
"cmd": ["/usr/bin/nodejs", "$file"],
"selector": "source.js"
}


Now the problem: if I move line
fs.readFile('test_underscore1.js', readFileDone);
above callback definitions, it does not run (no output in console and the file in
/tmp
does not get created either).

Why is that? After all, Javascript is supposed to parse entire file including function definitions before running? Therefore, the position of the line calling
fs.readFile
should not matter?

Answer

Seems to be a hoisting issue, your functions expressions are declared but not set until later on on the lines where you assigned them.

Effectively you have end up with:

"use strict";

var fs = require('fs');
var readFileDone,
      writeFile,
      writeFileDone;

fs.readFile('test_underscore1.js', readFileDone)

//  now your functions are assigned and available; after the above call

 readFileDone = function(err, data) {
    if(err) return console.error(err);
    console.log('read done');
    writeFile(null, data);
};

 writeFile = function(err, data) {
    if(err) return console.error(err);
    var ws = fs.createWriteStream('/tmp/copy.txt')
    ws.end(data, 'utf-8', writeFileDone);
};

 writeFileDone = function(err, data) {
    console.log('writing file done');
};

When you move the fs call above them you position it before they have been assigned the function definition (i.e. they aren't ready)