Heim  >  Fragen und Antworten  >  Hauptteil

javascript - Warum unterscheidet sich die Ausgabereihenfolge in Node.js von der erwarteten?

Untersuchen Sie den folgenden Code, der zur Ausgabe von Dateien im angegebenen Verzeichnis verwendet wird

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);        //开始执行
    }
});

Ich kann das Ausgabeergebnis des obigen Codes nicht verstehen. Gemäß der Logik dieses Programmdesigns sollten zuerst alle Dateien im Verzeichnis aufgelistet werden und dann der Zähler i==files.length verwendet werden, um den Endsatz „Ausgabe abgeschlossen“ auszugeben ".


Wie im Bild oben gezeigt, wird nicht nur das letzte Wort „Ausgabe abgeschlossen“ zuerst ausgegeben, sondern auch die Druckreihenfolge ist völlig durcheinander und die Druckreihenfolge mehrerer Durchläufe ist auch instabil.

Ich habe mich gefragt, ob es bei asynchronen Aufrufen einen Zeitunterschied gibt, also habe ich den Kommentarteil „sleep(1000)“ aus dem obigen Code entfernt, aber das Ergebnis stimmte immer noch nicht mit meinen Erwartungen überein: Die Eingabeaufforderung „Datei wie folgt“ wurde ausgegeben Zuerst und dann für 1 Sekunde angehalten, und die nachfolgenden Anweisungen waren fast gleichzeitig, es gibt keine Pause, und das letzte Wort „Ausgabe abgeschlossen“ ist immer noch das erste, das gedruckt wird.

Zusammenfassend möchte ich Folgendes wissen:

  1. Warum ist das Druckergebnis instabil? Warum wird zuerst die Meldung „Ausgabe abgeschlossen“ ausgegeben?

  2. Warum kommt es, dass nach dem Hinzufügen der Pause-Anweisung sleep(1000) zu Beginn nur eine Sekunde pausiert wird und dann nicht mehr pausiert, sondern gleichzeitig ausgegeben wird?

  3. Wie kann dieses Problem gelöst werden, d. h. wie kann die Eingabeaufforderung „Ausgabe abgeschlossen“ mit möglichst wenigen Änderungen endlich ausgegeben werden?

Danke für deinen Rat!

大家讲道理大家讲道理2698 Tage vor591

Antworte allen(2)Ich werde antworten

  • 大家讲道理

    大家讲道理2017-05-31 10:42:11

    1. fs.stat是异步操作,所以你的输出文件信息都是异步执行的,“输出完毕”肯定先打印的。想同步可以用这个https://nodejs.org/docs/lates...

    2. 在sleep里加个console.log('sleep')看是不是 只输出一次?

    3. 如果你想保证输出文件信息之后才输出“输出完毕”,第一点里我提到的用fs.statSync估计修改比较少吧

    Antwort
    0
  • PHP中文网

    PHP中文网2017-05-31 10:42:11

    根据@Dont的回答,确实是异步方法调用的原因,因为fs.stat的回调函数是在事件轮询中被调用,它一般在主程序运行间隙时候被调用,被调用时间和顺序不定。使用statSync方法可以实现同步:

    (function file(i){
        var filename=files[i];
        function read(stat){
            if(stat.isDirectory()){
                console.log(' '+i+' \033[36m 文件夹:'+filename+'/...\033[39m');
            }else{
                console.log(' '+i+' \033[36m 文件:'+filename+'\033[39m');
            }
        };
        read(fs.statSync(__dirname+'/'+filename));
        i++;
        ................

    Antwort
    0
  • StornierenAntwort