2016-07-24 4 views
0

Я пишу короткий скрипт с помощью Node и Commander. Он отобразит последние несколько строк данного файла. Я пытаюсь использовать чтение асинхронного файла в узле, но у меня ужасная проблема с настройкой обратных вызовов. Похоже, что код в обратном вызове выполняется перед родительской функцией. Возможно ли это?Обратный вызов Javascript, вызываемый перед родительской функцией

Вот сценарий:

#!/usr/bin/env node 

const readline = require('readline'); 
const fs = require('fs'); 
const program = require('commander'); 
const chalk = require('chalk'); 

var consoleArguments = process.argv; 

var fileValue =''; 
var linesArray = []; 

var main = function() { 

} 

function readFile(fileValue, callback){ 
    fs.readFile(fileValue, function(err, data) { 
     console.log("Hello from fs.readFile callback! \nReading file: " + fileValue); 
     var i = 0; 
     if(err) throw err; 
     linesArray = data.toString().split("\n"); 
     console.log("Hello from fs.readFile callback! Have just read the contents of file.\nThere are " + linesArray.length + " lines in the file!"); 
     for(i = 0; i <= linesArray.length - 1; i++) { 
      //console.log(i +": " + linesArray[i]); 
     } 
     console.log("Returned linesArray from fs.readFile callback!"); 
     return linesArray; 
    }); 
    console.log("Type of callback: " + typeof(callback)); 
    if (typeof callback === "function") { 
      // Call it, since we have confirmed it is callable​ 
      callback(linesArray); 
      console.log("Called callback"); 
    } 
} 



program 
    .version('0.0.1') 
    .arguments('<file>') 
    .usage('[options] <file>') 
    .option('-n, --number <number>', 'Display the last number of lines') 
    .option('-f, --follow', 'Follow the file and display the last 10 lines as new lines are appended') 
    .action(function(file) { 
     fileValue = file; 
    }) 
    .parse(process.argv); 

if(!program.args.length) { 
    program.help(); 
} else { 
    //console.log('Keywords: ' + program.args); 
    console.log("File: " + fileValue); 

    if (program.number && program.follow) { 
     console.log(' - follow'); 
     console.log(' - number'); 
     console.log('Number passed to number option: ' + program.number); 

    } else { 

     if (program.number) { 
      console.log(' - number'); 
      console.log('Number passed to number option: ' + program.number); 

      console.log(readFile(fileValue, function(linesArray){ 
       console.log("Hello from readFile callback! \nAbout to output file lines!"); 
       var i = 0; 
       var count = linesArray.length; 
       var totalString = ""; 

       console.log(count);  

       for (i = count - 11; i <= count - 1; i++) { 
        totalString += linesArray[i]; 
        totalString += '\n'; 
        console.log(linesArray[i]); 
       }   

      })); 
     } 

     if (program.follow) { 
     console.log(' - follow'); 
     }   
    } 
} 

if (program.args === null) program.help(); 

А вот затруднительный (по крайней мере, для меня) часть, выход. Короче говоря, я пытался настроить так, чтобы обратный вызов, выводящий нужные строки, вызывается, когда чтение файла завершено.

File: Word_List.txt 
    - number 
Number passed to number option: 10 
Type of callback: function 
Hello from readFile callback! 
About to output file lines! 
0 
undefined 
undefined 
undefined 
undefined 
undefined 
undefined 
undefined 
undefined 
undefined 
undefined 
undefined 
Called callback 
undefined 
Hello from fs.readFile callback! 
Reading file: Word_List.txt 
Hello from fs.readFile callback! Have just read the contents of file. 
There are 235887 lines in the file! 
Returned linesArray from fs.readFile callback! 

Edit1:

function writeLines(linesArray){ 
    console.log("Hello from writeLines callback! \nAbout to output file lines!"); 
    var i = 0; 
    var count = linesArray.length; 
    var totalString = ""; 

    console.log(count);  

    for (i = count - 11; i <= count - 1; i++) { 
     totalString += linesArray[i]; 
     totalString += '\n'; 
     console.log(linesArray[i]); 
    }   
} 

function readFile(fileValue, writeLines){ 
    fs.readFile(fileValue, function(err, data, writeLines) { 
     console.log("Hello from fs.readFile callback! \nReading file: " + fileValue); 
     var i = 0; 
     if(err) throw err; 
     linesArray = data.toString().split("\n"); 
     console.log("Hello from fs.readFile callback! Have just read the contents of file.\nThere are " + linesArray.length + " lines in the file!"); 
     for(i = 0; i <= linesArray.length - 1; i++) { 
      //console.log(i +": " + linesArray[i]); 
     } 
     writeLines(linesArray); 
    }); 
} 

Edit 2: Вот выход Edit1

File: Word_List.txt 
    - number 
Number passed to number option: 10 
/usr/local/lib/node_modules/test/NodeTail.js:44 
    writeLines(linesArray); 
    ^

TypeError: writeLines is not a function 
    at readFile (/usr/local/lib/node_modules/test/NodeTail.js:44:5) 
    at Object.<anonymous> (/usr/local/lib/node_modules/test/NodeTail.js:77:20) 
    at Module._compile (module.js:425:26) 
    at Object.Module._extensions..js (module.js:432:10) 
    at Module.load (module.js:356:32) 
    at Function.Module._load (module.js:313:12) 
    at Function.Module.runMain (module.js:457:10) 
    at startup (node.js:138:18) 
    at node.js:974:3 
+2

Вы выполняете обратный вызов вне обратного вызова 'fs.readFile', он должен находиться внутри' fs.readFle (..., function (err, data) {/ * здесь * /}); ' –

+0

Я понял это прежде, чем я увидел ваш комментарий. Я перекодировал некоторые вещи, и теперь я получаю 'TypeError: writeLines не функция 'в конце кода. – MadPhysicist

+1

@MadPhysicist вы можете опубликовать полный журнал и, возможно, выделить область в коде, на который вы ссылаетесь? –

ответ

1

fs.readFile является метод асинхронной, который означает, что вы будете читать когда он будет готов, поэтому остальная часть кода может быть обработана до тех пор, пока чтение не будет готово, так как ваш обратный вызов вызывается перед чтением файла.

Вы должны варианты:

  1. поставить функцию обратного вызова внутри fs.readFile обратного вызова в конце.
  2. вы можете использовать fs.readFileSync, который будет запускать ваш код синхронно, поэтому метод обратного вызова будет вызываться только после того, как вы закончите чтение файла.

Я думаю, что первый вариант лучше, потому что так работает Node.js.

+0

Я работал по строкам №1. Я редактировал вопрос. Теперь я получаю 'TypeError: writeLines не функция 'в самом конце. – MadPhysicist

+0

Готово. Спасибо за вашу помощь! – MadPhysicist

+0

@MadPhysicist добро пожаловать! –

Смежные вопросы