NodeJS和并行流

时间:2015-03-16 08:07:06

标签: node.js

我是NodeJS的新手。一个问题让我困惑的是并行流。我读了一个示例,将此片段显示为控制并行流的技术:

var fs = require('fs');
var fileDir = './files';

fs.readdir(filesDir, function (err, files) {
    if (err) throw err;

    for (var index in files) {
        var task = (function (file) {
            return function () {
                fs.readFile(file, function (err, text) {
                    if (err) throw err;
                    doSomething();
                });
            }
        })(filesDir + '/' + files[index]);

        tasks.push(task);
    }

    for (var index in tasks) {
        tasks[index]();
    }
});

这段代码就像魅力一样,但当我用

替换它时
    for (var index in files) {
        var task = function () {
            console.log(files[index]);
            fs.readFile(filesDir + '/' + files[index], function (err, text)   {
                if (err) throw err;
                doSomething();
            });
        };

        tasks.push(task);
    }

    for (var index in tasks) {
        tasks[index]();
    }

它没有像我预期的那样工作,因为循环中的 files [index] 始终是目录中的最后一个文件。能否请您解释一下真正的流程是什么?

2 个答案:

答案 0 :(得分:1)

简而言之,您创建的函数引用了索引变量(而不是它的值),因此当它执行时,索引值是您案例中目录中的最后一个文件。

部分链接:Understanding variable capture by closures in Javascript/Node

答案 1 :(得分:1)

因为索引引用将是它的最后一个文件。节点js是异步的,它不会等到读取文件操作完成。它会增加索引值。

for (var index in files) {
    var task = function () {
        console.log(files[index]);
        fs.readFile(filesDir + '/' + files[index], function (err, text)   {
            if (err) throw err;
            doSomething();
        });
    };

    tasks.push(task);
}

由于第一个代码使用闭包,它将当前索引文件传递给函数。它将获取当前索引文件并返回一个函数,并将该文件作为输入。

现在返回的函数将并行执行。