learnyounode
learnyounode copied to clipboard
coding style questions about first async io
I've completed the first asyc challenge and have a few questions. Please see inline commentary:
- My error handling is basic. What would be a good way to catch if someone hadn't entered a file argument?
- Is there a better way to write this asynchronously? I saw a TedTalk where (the Godfather) Linus said it was bad taste to use an if statement. Perhaps it was contextual, but could this be written with better taste? perhaps a While ?
- What is good practice. Console.log here or console.log in the global context?
var fs = require('fs');
function countNewLines(){
fs.readFile(process.argv[2], 'utf8', function doneReading(err, fileContents) {
/* My error handling is basic. What would be a good way to catch if someone
hadn't entered a file argument?
Is there a better way to write this asynchronously? I saw a TedTalk
where (the Godfather) Linus said it was bad taste to use an if statement, perhaps
contextual to his example ,but could this be written with better taste ? ..a While ? */
if (err) throw err;
else {
var countNewLineChar = fileContents.split('\n').length -1;
/* what is good practice. Console.log here or console.log in the
global context? */
console.log(countNewLineChar);
};
});
};
countNewLines();
For instance:
var fs = require('fs');
function countNewLines(){
fs.readFile(process.argv[2], 'utf8', function doneReading(err, fileContents) {
/* My error handling is basic. What would be a good way to catch if someone
hadn't entered a file argument?
Is there a better way to write this asynchronously? I saw a TedTalk
where (the Godfather) Linus said it was bad taste to use an if statement, perhaps
contextual to his example ,but could this be written with a while ? */
while (!err) {
var countNewLineChar = fileContents.split('\n').length -1;
/* what is good practice. Console.log here or console.log in the
global context? */
console.log(countNewLineChar);
return;
};
});
};
countNewLines();
The callback here is called exactly once. Either an error happen or you received your data, not both. You can improve your error handling by checking the code
property. For example, checking if (err && err.code === 'ENOENT')
will tell you that the argument you received is a non-existent file location.
Where you decide to use console.log
is not strictly important except that the data must be in scope. When doing async work, you can't really put the console.log in global scope. You can keep it as close as possible for readability sake, but this is your choice. Here is what you might have done if you wanted this code to be highly flexible (and thus reusable).
var fs = require('fs');
function countNewLines(filename, callback) {
fs.readFile(filename, 'utf8', function(err, contents) {
if (err) return callback(err); // or better error checking if needed
var count = contents.split('\n').length - 1;
callback(null, count);
});
}
countNewLines(process.argv[2], function(err, count) {
if (err) return console.error(err);
console.log(count);
});
That is probably pretty useless, but hopefully you see how it allows consumers of countNewLines
to do what they need. The "http collect" exercise is a bit of a better example. Making a flexible function allows that same function to be used in the "juggling async" exercise.
--
P.S. I lied earlier. You might receive both an error and data in your callback. However, if you get an error at all, consider any data you received to be invalid.