Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add async callback to eachLine

  • Loading branch information...
commit a785d61d5fedd8e29ad3efb1acad2ff5286fa59e 1 parent 10c5cf1
@nickewing authored
Showing with 86 additions and 15 deletions.
  1. +17 −3 README.md
  2. +30 −11 lib/line_reader.js
  3. +1 −1  package.json
  4. +38 −0 test/line_reader.js
View
20 README.md
@@ -11,21 +11,35 @@ Install
Usage
-----
-The `eachLine` method reads each line of the given file. Upon each new line,
+The `eachLine` function reads each line of the given file. Upon each new line,
the given callback function is called with two parameters: the line read and a
boolean value specifying whether the line read was the last line of the file.
If the callback returns `false`, reading will stop and the file will be closed.
var lineReader = require('line-reader');
-
+
lineReader.eachLine('file.txt', function(line, last) {
console.log(line);
-
+
if (/* done */) {
return false; // stop reading
}
});
+`eachLine` can also be used in an asynchronous manner by providing a third
+callback parameter like so:
+
+ var lineReader = require('line-reader');
+
+ lineReader.eachLine('file.txt', function(line, last, cb) {
+ console.log(line);
+
+ if (/* done */) {
+ cb(false); // stop reading
+ } else {
+ cb();
+ }
+ });
The `eachLine` function also returns an object with one property, `then`. If a
callback is provided to `then`, it will be called once all lines have been read.
View
41 lib/line_reader.js
@@ -115,30 +115,49 @@
}
function eachLine(filename, cb, separator, encoding, bufferSize) {
- var finalFn;
+ var finalFn,
+ asyncCb = cb.length == 3;
function finish() {
if (finalFn && typeof finalFn === 'function') {
- // let the caller know that we're done
finalFn();
}
}
open(filename, function (reader) {
- function read() {
+ function newRead() {
if (reader.hasNextLine()) {
- reader.nextLine(function (line) {
- if (cb(line, !reader.hasNextLine()) !== false) {
- read();
- } else {
- finish();
- }
- });
+ process.nextTick(readNext);
} else {
finish();
}
}
- read();
+
+ function continueCb(continueReading) {
+ if (continueReading !== false) {
+ newRead();
+ } else {
+ finish();
+ }
+ }
+
+ function readNext() {
+ reader.nextLine(function(line) {
+ var last = !reader.hasNextLine();
+
+ if (asyncCb) {
+ cb(line, last, continueCb);
+ } else {
+ if (cb(line, last) !== false) {
+ newRead();
+ } else {
+ finish();
+ }
+ }
+ });
+ }
+
+ newRead();
}, separator, encoding, bufferSize);
return {
View
2  package.json
@@ -1,6 +1,6 @@
{
"name": "line-reader",
- "version": "0.1.5",
+ "version": "0.2.0",
"description": "Asynchronous line-by-line file reader",
"url": "https://github.com/nickewing/line-reader",
"keywords": ["file", "line", "reader", "scanner"],
View
38 test/line_reader.js
@@ -34,6 +34,26 @@ describe("lineReader", function() {
});
});
+ it("should allow continuation of line reading via a callback", function(done) {
+ var i = 0;
+
+ lineReader.eachLine(testFilePath, function (line, last, cb) {
+ assert.equal(testFile[i], line, 'Each line should be what we expect');
+ i += 1;
+
+ if (i === 6) {
+ assert.ok(last);
+ } else {
+ assert.ok(!last);
+ }
+
+ process.nextTick(cb);
+ }).then(function() {
+ assert.equal(6, i);
+ done();
+ });
+ });
+
it("should separate files using given separator", function(done) {
var i = 0;
lineReader.eachLine(separatorFilePath, function (line, last) {
@@ -66,6 +86,24 @@ describe("lineReader", function() {
});
});
+ it("should allow early termination of line reading via a callback", function(done) {
+ var i = 0;
+ lineReader.eachLine(testFilePath, function (line, last, cb) {
+ assert.equal(testFile[i], line, 'Each line should be what we expect');
+ i += 1;
+
+ if (i === 2) {
+ cb(false);
+ } else {
+ cb();
+ }
+
+ }).then(function() {
+ assert.equal(2, i);
+ done();
+ });
+ });
+
it("should not call callback on empty file", function(done) {
lineReader.eachLine(emptyFilePath, function (line) {
assert.ok(false, "Empty file should not cause any callbacks");
Please sign in to comment.
Something went wrong with that request. Please try again.