javascript - Why is the output order in Node.js different from expected?
大家讲道理
大家讲道理 2017-05-31 10:40:11
0
2
622

Examine the following code, which is used to output files in the specified directory

var fs=require('fs');

function sleep(numberMillis) {     //sleep方法,暂停numberMillis毫秒
    var now = new Date(); 
    var exitTime = now.getTime() + numberMillis; 
    while (true) { 
        now = new Date(); 
        if (now.getTime() > exitTime) 
            return; 
    } 
}

fs.readdir(__dirname,function(err,files){    //文件读取方法
    console.log('');
    if(!files.length){
        console.log('找不到文件 \n');
    }else{
        console.log('文件如下:');
        function file(i){
            var filename=files[i];
            fs.stat(__dirname+'/'+filename,function(err,stat){
                if(stat.isDirectory()){
                    console.log(' '+i+'文件夹:'+filename+'/...');
                }else{
                    console.log(' '+i+'文件:'+filename+'');
                }
            });
            i++;
            //sleep(1000);    //。。。。。。。。######暂停1s    
            if(i==files.length){
                console.log('输出完毕');
            }else{
                file(i);    //否则递归调用
            }
        }
        file(0);        //开始执行
    }
});

I can’t understand the result output by the above code. According to the logic of this program design, all files in the directory should be listed first, and then the counter i==files.length should be output before "Output completed" is the final word.


As shown in the picture above, not only is the terminal word "output completed" output first, but the printing order is completely messed up, and the printing order of multiple runs is also unstable.

I was wondering if there was a time difference in asynchronous calls, so I removed the sleep(1000) comment part of the above code, but the result was still inconsistent with what I expected: The "file is as follows" prompt was output first, and then stopped after 1s. , the subsequent statements are issued almost at the same time, without pause, and the terminal word "output completed" is still the first to be printed .

To sum up, what I want to know is

  1. Why is the printing result unstable and why is the prompt "output completed" output first?

  2. Why after adding the pause statement sleep(1000), it only pauses for 1s at the beginning, and then it no longer pauses but outputs simultaneously?

  3. How to solve this problem, that is, how to make the prompt "Output Complete" finally output with as few modifications as possible?

Thank you for your advice!

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

reply all(2)
大家讲道理
  1. fs.stat is an asynchronous operation, so your output file information is executed asynchronously, and "output completed" must be printed first. If you want to synchronize, you can use this https://nodejs.org/docs/lates...

  2. Add a console.log('sleep') to sleep to see if it only outputs once?

  3. If you want to ensure that "output completed" is output only after outputting the file information, using fs.statSync as I mentioned in the first point probably requires less modification

Ty80

According to @Dont's answer, it is indeed the reason for the asynchronous method call, because the callback function of fs.stat is called in event polling. It is usually called during the gap between the main program running, and the time and order of being called are uncertain. Synchronization can be achieved using the statSync method:

(function file(i){
    var filename=files[i];
    function read(stat){
        if(stat.isDirectory()){
            console.log(' '+i+' 3[36m 文件夹:'+filename+'/...3[39m');
        }else{
            console.log(' '+i+' 3[36m 文件:'+filename+'3[39m');
        }
    };
    read(fs.statSync(__dirname+'/'+filename));
    i++;
    ................
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template