使用async的Node.js - 如何在fs.readFile中正确使用async.forEachLimit?

时间:2014-04-24 20:58:20

标签: javascript node.js asynchronous file-io package

我正在开发Node.js应用程序的一部分,该应用程序需要从各种文件中的特定点获取版本信息。我使用npm包async。

编写了这个功能

我确切地知道我的问题是什么。但是,因为我对Node.js这么新,甚至更新的异步包,我没有正确实现。

似乎版本变量的内容没有及时响应我的回复。换句话说,响应是在版本进入响应之前发送的。

以下是相关代码:

exports.getAllVersionInformation = function(request, response) {
    if (!utilities.checkLogin(request, response))
        return;

    // Get the array of file information stored in the config.js file
    var fileCollection = config.versionsArray;

    // Declare the array to be used for the response
    var responseObjects = [];

    async.forEachLimit(fileCollection, 1, function(fileInformation, taskDone) {
        // Declare an object to be used within the response array
        var responseObject = new Object();

        // Retrieve all information particular to the given file
        var name = fileInformation[0];
        var fullPath = fileInformation[1];
        var lineNumber = fileInformation[2];
        var startIndex = fileInformation[3];
        var endIndex = fileInformation[4];

        // Get the version number in the file
        var version = getVersionInFile(fullPath, lineNumber, startIndex,
                endIndex, taskDone);

        console.log('Ran getVersionInFile()');

        // Set the name and version into an object
        responseObject.name = name;
        responseObject.version = version;

        // Put the object into the response array
        responseObjects.push(responseObject);

        console.log('Pushed an object onto the array');

    }, function(error) {
        console.log('Entered the final');

        if (error == null)
            // Respond with the JSON representation of the response array
            response.json(responseObjects);
        else
            console.log('There was an error: ' + error);
    });
};

function getVersionInFile(fullPath, lineNumber, startIndex, endIndex, taskDone) {
    console.log('Entered getVersionInFile()');
    var version = fs.readFile(fullPath,
            function(error, file) {
                if (error == null) {
                    console.log('Reading file...');

                    var lineArray = file.toString().split('\n');

                    version = lineArray[lineNumber].substring(startIndex,
                            endIndex + 1);
                    console.log('The file was read and the version was set');
                    taskDone();
                } else {
                    console.log('There was a problem with the file: ' + error);
                    version = null;
                    taskDone();
                }
            });
    console.log('Called taskDone(), returning...');
    return version;
};

我试过玩getVersionInFile函数如何返回数据。我已经移动了taskDone()函数,看看是否会产生影响。我已经向谷歌询问了很多关于异步的问题以及在我的上下文中使用它的方法。我似乎无法让它发挥作用。

我使用的一些更重要的资源是: http://www.sebastianseilund.com/nodejs-async-in-practice http://book.mixu.net/node/ch7.html

我添加了console.log语句以获取代码流的跟踪。这是图片: Console Output

此外,我有一些我期待的回应。这也是: ![浏览器输出] http://imgur.com/rKFq83y

此输出的问题是JSON中的每个对象也应具有版本值。所以,JSON应该类似于: [{ “名称”: “的WebSphere”, “版本”: “X.X.X.X”},{ “名称”: “COGNOS”, “版本”: “X.X.X.X”}]

如何让我的getVersionInFile()函数及时正确地给我版本号?另外,如何在不进行任何阻塞的情况下确保异步执行此操作(使用异步进行流控制的原因)?

非常感谢任何见解或建议。

1 个答案:

答案 0 :(得分:1)

一个问题是getVersionInFile()在异步readFile()完成之前返回一个值(也是异步,readFile()没有返回有意义的值)。此外,对forEachLimit()使用限制/并发1与forEachSeries()相同。这是一个使用mapSeries()的示例,它可以获得相同的最终结果:

exports.getAllVersionInformation = function(request, response) {
  if (!utilities.checkLogin(request, response))
    return;

  // Get the array of file information stored in the config.js file
  var fileCollection = config.versionsArray;

  async.mapSeries(fileCollection, function(fileInformation, callback) {
    // Retrieve all information particular to the given file
    var name = fileInformation[0];
    var fullPath = fileInformation[1];
    var lineNumber = fileInformation[2];
    var startIndex = fileInformation[3];
    var endIndex = fileInformation[4];

    // Get the version number in the file
    getVersionInFile(fullPath,
                     lineNumber,
                     startIndex,
                     endIndex,
                     function(error, version) {
      if (error)
        return callback(error);

      callback(null, { name: name, version: version });
    });
  }, function(error, responseObjects) {
    if (error)
      return console.log('There was an error: ' + error);

    // Respond with the JSON representation of the response array
    response.json(responseObjects);
  });
};

function getVersionInFile(fullPath, lineNumber, startIndex, endIndex, callback) {
  fs.readFile(fullPath,
              { encoding: 'utf8' },
              function(error, file) {
                if (error)
                  return callback(error);

                var lineArray = file.split('\n');

                version = lineArray[lineNumber].substring(startIndex,
                        endIndex + 1);
                callback(null, version);
              });
};