Node.js / Is for循环是异步吗?

时间:2015-02-23 19:56:17

标签: javascript node.js asynchronous

我有以下代码:

for (var i = 0; i < files.length; i++) {
    var data = fs.readFileSync(files[i]);
    fs.appendFileSync("file_part", data);
}

我们说我有1000个文件。它是for循环异步吗?或者我的应用程序将等到它完成该过程?

如果它同步,我如何使它异步?所以每个迭代都是异步的吗?

修改

此代码是使用express的服务器代码的一部分。我们收到了很多https请求,并为客户提供服务。其中一个操作是将1MB的文件附加到一个大文件中。如果操作成功,服务器应返回200,否则返回500.

问题在于,如果执行上面的代码(for循环),快递模块将停止为其他客户端提供服务,并且它会忙碌&#34;有这个要求。我尝试使用async.eachSeries(因为文件的顺序有意义,所以我必须使用Series方法),但它仍然卡在服务器上。

3 个答案:

答案 0 :(得分:1)

JS中的所有控制结构都是同步执行的。由于您在循环体中没有使用异步函数(但是明确同步的对应函数),它将等待它们完成任务。


要使代码段无阻塞,您需要使用常规的异步fs方法,并对其进行适当的链接。我建议使用promises,但是如果你已经使用,那么它应该是这样的:

async.eachSeries(files, function(file, cb) {
    fs.readFile(file, function(err, data) {
        if (err) return cb(err);
        fs.appendFile("file_part", data, cb);
    });
}, function(err) {
    // call back to express here with 500 if err and 200 otherwise
});

答案 1 :(得分:0)

问题和你要做的事情都有几个问题。您可能想要澄清问题或澄清您真正想做的事情。

对您的问题的简短回答:否.A循环本身不是异步的。

答案略长:目前尚不清楚您是否需要将循环本身设为异步,但您可能只希望内容为异步。因此,您可能希望使用readFileSync进行回调,而不是调用readFile。在此回调中,您可以附加到该文件。这将“触发”1000个读取文件,这些文件将在准备好时调用它们的回调。

但仍然存在问题。如果您异步读取1000个文件,并将它们保存到您读取的同一个文件中,则不会以任何顺序获取文件内容,甚至可能有文件内容交错。我无法想象为什么你真的想要这样做。

更新:您更新的问题仍然有点模糊 - 如果您需要等到一切都完成后发送代码200回复​​...那么您将不得不等到所有附加文件。实际上没有任何其他解决方案。

但是,如果您可以立即返回代码200以指示您正在处理该文件追加,然后在后台执行追加,则可以将该循环作为异步任务的一部分执行。您可以在process.nextTick()电话或承诺中或以对您的流量有意义的任何其他方式执行此操作。

答案 2 :(得分:0)

如果您只想异步连接文件列表,则可以在回调fs.readFile中执行此操作:

function concatFiles (source_array, destination) {
    var source = source_array.shift();

    fs.readFile(source,function(err,data){
        fs.appendFile(destination,data,function(err){
            if (source_array.length) {
                concatFiles(source_array, destination);
            }
        });
    });
}

// Usage:
concatFiles(files,"file_part");

请注意,为清楚起见,我没有处理上面代码中的错误。在生产代码中,您应该检查错误并适当地处理它们。

相当明显的是发生了什么。弹出源列表中的第一个文件。然后异步读取该文件。然后,当完成时异步写入目标文件。重复,直到源列表为空。