【问题标题】:Node.js using async - How can I properly use async.forEachLimit with fs.readFile?Node.js 使用 async - 如何正确使用 async.forEachLimit 和 fs.readFile?
【发布时间】:2014-04-25 05:33:07
【问题描述】:

我正在开发 Node.js 应用程序的一部分,该应用程序需要从各种文件中的特定点获取版本信息。我已经使用 npm 包 async 对此功能进行了编码。

我确切地知道我的问题是什么。但是,因为我对 Node.js 还很陌生,甚至对 async 包也很陌生,所以我没有实现正确的东西。

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

下面是相关代码:

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() 函数,看看是否会有所作为。我已经向 Google 询问了很多关于异步以及在我的上下文中使用它的方式的问题。我似乎无法让它工作。

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

我添加了 console.log 语句来跟踪代码流。这是图片:

此外,我得到了部分预期的响应。这也是: ![浏览器输出]http://imgur.com/rKFq83y

这个输出的问题是 JSON 中的每个对象也应该有一个版本值。因此,JSON 应该类似于: [{"name":"WebSphere","version":"x.x.x.x"},{"name":"Cognos","version":"x.x.x.x"}]

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

任何见解或建议将不胜感激。

【问题讨论】:

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


    【解决方案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);
                  });
    };
    

    【讨论】:

    • 你成功了。继续当老板。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 2020-08-23
    • 1970-01-01
    • 2019-04-21
    • 2017-12-02
    • 2014-10-19
    相关资源
    最近更新 更多