使用fs.readFile的简单nodejs回调示例

时间:2013-12-18 00:17:27

标签: javascript node.js asynchronous callback

我正在尝试学习异步编程,并且正在努力学习nodeschool.io的第4课,并实现了带回调的异步io。

基本上,我正在尝试使用fs.readFile来计算使用回调的文件中的换行数。

这是我的代码:

var fs = require('fs');
var pathToFile = process.argv[2];

function counter(callback) {
    var buffer = fs.readFile(pathToFile, function (err, data) {
    var bufferString = buffer.toString();
    var bufferStringSplit = bufferString.split('\n');
  });
  callback();
}

function logMyNumber() {
  console.log(bufferStringSplit.length-1);
}

counter(logMyNumber);

我知道一旦代码行执行完毕就会执行回调,所以不应该

var bufferString = buffer.toString();
var bufferStringSplit = bufferString.split('\n');

在fs.readFile()完成从磁盘读取文件后调用?

然后最后callback()调用logMyNumber,它应该只输出文件所包含的行数。

3 个答案:

答案 0 :(得分:14)

您有几个问题正在进行中,我将尝试尽可能地概述它们

问题1:可变范围

var fs = require('fs');
var pathToFile = process.argv[2];

function counter(callback) {
  var buffer = fs.readFile(pathToFile, function (err, data) { 
    // Both of the following variables are scoped to the callback of fs.readFile
    var bufferString = buffer.toString(); 
    var bufferStringSplit = bufferString.split('\n'); 
  });
  callback();
}

function logMyNumber() {
  // Because the variables are in a closure above, bufferStringSplit is null here
  console.log(bufferStringSplit.length-1);
}

counter(logMyNumber);

解决方案:

声明模块范围内的变量:

var fs = require('fs');
var pathToFile = process.argv[2];

// These can now be accessed from anywhere within the module
var bufferString, bufferStringSplit;

function counter(callback) {
  fs.readFile(pathToFile, function (err, data) {
    bufferString = data.toString(); 
    bufferStringSplit = bufferString.split('\n'); 
    callback();
  });
}

// bufferStringSplit should no longer return null here
function logMyNumber() {
  console.log(bufferStringSplit.length-1);
}

问题2:回调

function counter(callback) {
  fs.readFile(pathToFile, function (err, data) {
    bufferString = buffer.toString(); 
    bufferStringSplit = bufferString.split('\n'); 

    // Place the callback WITHIN the other callback, otherwise they run in parallel
    callback();
  });
}

问题3:fs.readFile API

fs.readFile不返回任何内容,因此下面的buffer变量为null

function counter(callback) {      
  var buffer = fs.readFile(pathToFile, function (err, data) {
    bufferString = buffer.toString(); 
    bufferStringSplit = bufferString.split('\n'); 
  });
  callback();
}

解决方案:

function counter(callback) {      
  fs.readFile(pathToFile, function (err, data) {
    // The data argument of the fs.readFile callback is the data buffer
    bufferString = data.toString(); 
    bufferStringSplit = bufferString.split('\n'); 
  });
  callback();
}

最后,代码应如下所示:

var fs = require('fs');
var pathToFile = process.argv[2];

var bufferString, bufferStringSplit;

function counter(callback) {
  fs.readFile(pathToFile, function (err, data) {
    bufferString = data.toString(); 
    bufferStringSplit = bufferString.split('\n'); 
    callback();
  });
}

function logMyNumber() {
  console.log(bufferStringSplit.length-1);
}

counter(logMyNumber);

答案 1 :(得分:1)

对我来说同样的问题。这是我的解决方案。

var fs = require('fs');
var file = process.argv[2];

function count(pFile, callback) {
  fs.readFile(pFile, "utf8", function(err, data){
     callback(data.split("\n").length-1);
  });
}

count(file, console.log);

答案 2 :(得分:1)

尝试 处理错误 。不确定,如果最好在最后一个回调中传播错误。我认为功能是非常基本的,但无论如何我正在传播错误。

我还会说 委托 中的 拆分 更为正确最后回调 ,而不是通过参数或类似的传递。

var fs = require('fs');
var myfile = process.argv[2];



function solution(file, callback){
fs.readFile(file, "utf-8", function (err, data) {
    if (err) callback(err);
    callback(null, data)
});
}

function mycallback(err,data){
  if (err) callback(err) console.error(err);
  return data.split('\n').length-1);
}

solution(myfile,mycallback)