Asynchronous file reading not asynchronous or programmer poop?

133 views
Skip to first unread message

Maverick Peppers

unread,
Jan 24, 2015, 6:25:29 PM1/24/15
to nod...@googlegroups.com
// Start of program4 process
var fs = require('fs');

// Asyncronously read and send the buffer object of a file whose path
// is set int 2nd argument of the process to the callback function.
var buffer = 0;
fs.readFile(process.argv[2], fileReadCallBack);

while(buffer == 0) {}

var numOfNewLines = buffer.toString().split('\n').length-1;
console.log(numOfNewLines);

// Our callback function for our asyncronous file reading
function fileReadCallBack(err, data) { if(!err){ buffer = data; } }

I'm using NodeSchool.io's workshop to learn Nodejs. I'm on problem 4, Async File I/O and the above code runs forever. If the file reading is asynchronous, I'm thinking var buffer should no longer be 0 and the while-loop will terminate and move on. 

I know the correct solution would place the logic inside of the callback function, but I'm curious as to why the code above doesn't work as expected.

Thanks!

Adrien Risser

unread,
Jan 24, 2015, 7:15:56 PM1/24/15
to nod...@googlegroups.com
On Sun, Jan 25, 2015 at 12:25 AM, Maverick Peppers <bmpe...@gmail.com> wrote:
// Start of program4 process
var fs = require('fs');

// Asyncronously read and send the buffer object of a file whose path
// is set int 2nd argument of the process to the callback function.
var buffer = 0;
fs.readFile(process.argv[2], fileReadCallBack);

while(buffer == 0) {}


Code is blocked here as instructions are executed sequentially.
fileReadCallback is never called as you never free the thread's execution.
 
var numOfNewLines = buffer.toString().split('\n').length-1;
console.log(numOfNewLines);

// Our callback function for our asyncronous file reading
function fileReadCallBack(err, data) { if(!err){ buffer = data; } }

I'm using NodeSchool.io's workshop to learn Nodejs. I'm on problem 4, Async File I/O and the above code runs forever. If the file reading is asynchronous, I'm thinking var buffer should no longer be 0 and the while-loop will terminate and move on. 

I know the correct solution would place the logic inside of the callback function, but I'm curious as to why the code above doesn't work as expected.

Thanks!

Try this:


var buffer = 0;

console.log('outside setTimeout');

setTimeout(function () {
  console.log('inside setTimeout');
  buffer = 1;
}, 10);

console.log('before while');

while(buffer == 0) {}

console.log('after while');



 Cheers,

--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/635a38d4-4f7c-402c-b841-7b682814143e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Adrien Risser,
Freelance Node.js Consultant

Thomas Shinnick

unread,
Jan 24, 2015, 7:16:02 PM1/24/15
to nod...@googlegroups.com
On Sat, Jan 24, 2015 at 5:25 PM, Maverick Peppers <bmpe...@gmail.com> wrote:
while(buffer == 0) {}

The above line does not mean wait around 'awhile', it means "run forever, not giving anyone else any CPU time to do anything or respond to anything".  You are not 'cooperating' with Node or anyone else. 

There are a number of ways/ideas to say "let me wait around until the system/Node can respond", but this would be one replacement for the above line:

while ( buffer == 0 ) 
    process.nextTick();

With that you are saying "let me check on something fairly often, but if it hasn't happened yet, give me control to the system/Node so it can do 'whatever' needs to be done".

Ryan Schmidt

unread,
Jan 24, 2015, 7:16:04 PM1/24/15
to nod...@googlegroups.com
Because the line

> while(buffer == 0) {}

blocks the event loop.

Angel Java Lopez

unread,
Jan 24, 2015, 7:16:06 PM1/24/15
to nod...@googlegroups.com
The file read could be async, but your code fileReadCallBack will never be called.

After fs.readFile(...) all the async magic take place, OK.

BUT YOUR JAVASCRIPT code will run the next command, after fs.readFile. It is an infinite loop, becase fileReadCallBack will be called when your JavaScript code free the JavaScript machine, so it can attend any callback

If you don't free the JavaScript machine, fileReadCallBack will never executed, and your buffer will be empty for ever

Maybe better is

fs.readFile(process.argv[2], fileReadCallBack);

// Our callback function for our asyncronous file reading
function fileReadCallBack(err, data) { 
  if(err)
      return; // or maybe better, inform the problem
var numOfNewLines = data.toString().split('\n').length-1;
console.log(numOfNewLines);

} }

Apologize my English ;-)

Angel "Java" Lopez
@ajlopez


--

genericlady

unread,
Jan 27, 2015, 11:53:39 AM1/27/15
to nod...@googlegroups.com
The while statement is an infinite loop because it doesn't have a break.  From top to bottom you have your fs object so that's good.  Since your setting up your objects maybe even put the path into it's own ;)

The readFile method is not being used correctly. The way a callback works in Node.js is you pass an anonymous function as the callback.  When reading documentation for fs.readFile this is what we see.

fs.readFile('/etc/passwd', function (err, data) {

  if (err) throw err;

  console.log(data);

});

Hope this helps!

Reply all
Reply to author
Forward
0 new messages