Node.js 同步与异步

我目前正在学习 node.js,我看到了 2 个同步和异步程序示例(同一个).

I'm currently learning node.js and I see 2 examples for sync and async program (same one).

我确实了解回调的概念,但我试图了解第二个(异步)示例的好处,因为即使存在这种差异,他们两个似乎也在做完全相同的事情......

I do understand the concept of a callback, but i'm trying to understand the benefit for the second (async) example, as it seems that the two of them are doing the exact same thing even though this difference...

您能否详细说明为什么第二个示例会更好?我很高兴得到更广泛的解释,这将有助于我理解这个概念..

Can you please detail the reason why would the second example be better? I'll be happy to get an ever wider explanation that would help me understand the concept..

谢谢!!

第一个例子:

var fs = require('fs');

function calculateByteSize() {
    var totalBytes = 0,
        i,
        filenames,
        stats;
    filenames = fs.readdirSync(".");
    for (i = 0; i < filenames.length; i ++) {
        stats = fs.statSync("./" + filenames[i]);
        totalBytes += stats.size;
    }
    console.log(totalBytes);
}

calculateByteSize();

第二个例子:

var fs = require('fs');

var count = 0,
    totalBytes = 0;

function calculateByteSize() {
    fs.readdir(".", function (err, filenames) {
        var i;
        count = filenames.length;

        for (i = 0; i < filenames.length; i++) {
            fs.stat("./" + filenames[i], function (err, stats) {
                totalBytes += stats.size;
                count--;
                if (count === 0) {
                    console.log(totalBytes);
                }
            });
        }
    });
}

calculateByteSize();

推荐答案

你的第一个例子是所有阻塞 I/O.换句话说,您需要等到 readdir 操作完成后才能遍历每个文件.然后,您需要阻止(等待)每个单独的同步统计操作运行,然后再转到下一个文件.calculateByteSize() 调用后,在所有操作完成之前,没有代码可以运行.

Your first example is all blocking I/O. In other words, you would need to wait until the readdir operation is complete before looping through each file. Then you would need to block (wait) for each individual sync stat operation to run before moving on to the next file. No code could run after calculateByteSize() call until all operations are completed.

另一方面,异步(第二个)示例使用回调模式是非阻塞的.在这里,只要调用 fs.readdir(但在运行回调之前),执行就会立即返回到 calculateByteSize() 调用之后.一旦 readdir 任务完成,它就会对您的匿名函数执行回调.在这里,它遍历每个文件并再次对 fs.stat 进行非阻塞调用.

The async (second) example on the otherhand is all non-blocking using the callback pattern. Here, the execution returns to just after the calculateByteSize() call as soon as fs.readdir is called (but before the callback is run). Once the readdir task is complete it performs a callback to your anonymous function. Here it loops through each of the files and again does non-blocking calls to fs.stat.

第二个更有利.如果您可以假装对 readdir 或 stat 的调用可以在 250 毫秒到 750 毫秒之间完成(这可能不是这种情况),那么您将等待对同步操作的串行调用.但是,异步操作不会导致您在每次调用之间等待.换句话说,遍历 readdir 文件,如果您同步执行,则需要等待每个 stat 操作完成.如果您要异步执行此操作,则不必等待调用每个 fs.stat 调用.

The second is more advantageous. If you can pretend that calls to readdir or stat can range from 250ms to 750ms to complete (this is probably not the case), you would be waiting for serial calls to your sync operations. However, the async operations would not cause you to wait between each call. In other words, looping over the readdir files, you would need to wait for each stat operation to complete if you were doing it synchronously. If you were to do it asynchronously, you would not have to wait to call each fs.stat call.

相关文章