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

end*_*cat 2 javascript asynchronous callback node.js

我正在尝试学习异步编程,并且正在努力学习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);
Run Code Online (Sandbox Code Playgroud)

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

var bufferString = buffer.toString();
var bufferStringSplit = bufferString.split('\n');
Run Code Online (Sandbox Code Playgroud)

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

最后,callback()调用logMyNumber,它应该只输出文件所具有的行数.

srq*_*inn 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);
Run Code Online (Sandbox Code Playgroud)

解:

声明模块范围内的变量:

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);
}
Run Code Online (Sandbox Code Playgroud)

问题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();
  });
}
Run Code Online (Sandbox Code Playgroud)

问题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();
}
Run Code Online (Sandbox Code Playgroud)

解:

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();
}
Run Code Online (Sandbox Code Playgroud)

最后,代码应如下所示:

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);
Run Code Online (Sandbox Code Playgroud)

  • @EmptyArsenal你是完全正确的.如果这是另一个消耗的模块,则在模块范围中实例化变量并在模块的各种方法中操作它们可能会产生一些意外行为.毕竟,封装是良好OOP的支柱.但是,由于OP的代码中存在很多问题,我认为要深入了解优秀的OOP设计细节. (2认同)