javascript - Pourquoi l'ordre de sortie dans Node.js est-il différent de celui attendu?
大家讲道理
大家讲道理 2017-05-31 10:40:11
0
2
646

Examinez le code suivant, qui est utilisé pour générer des fichiers dans le répertoire spécifié

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

Je ne comprends pas le résultat de sortie du code ci-dessus. Selon la logique de la conception de ce programme, tous les fichiers du répertoire doivent être répertoriés en premier, puis le compteur i==files.length doit être utilisé pour afficher la phrase du terminal "Sortie terminée. ".


Comme le montre l'image ci-dessus, non seulement le dernier mot « Sortie terminée » est affiché en premier, mais l'ordre d'impression est complètement foiré et l'ordre d'impression de plusieurs tirages est également instable.

Je me demandais s'il y avait un décalage horaire dans les appels asynchrones, j'ai donc supprimé la partie commentaire sleep(1000) du code ci-dessus, mais le résultat était toujours incohérent avec ce à quoi je m'attendais : L'invite "Fichier comme suit" a été affichée d'abord, puis arrêté pendant 1 seconde, et les déclarations suivantes étaient presque en même temps, il n'y a pas de pause, et le dernier mot « sortie terminée » est toujours le premier à être imprimé.

Pour résumer, ce que je veux savoir, c'est

  1. Pourquoi le résultat de l'impression est-il instable ? Pourquoi l'invite « sortie terminée » est-elle affichée en premier ?

  2. Pourquoi est-ce qu'après avoir ajouté l'instruction pause sleep(1000), il ne fait une pause que pendant 1 seconde au début, puis il ne fait plus de pause mais sort simultanément ?

  3. Comment résoudre ce problème, c'est-à-dire comment faire en sorte que l'invite « Sortie terminée » s'affiche enfin avec le moins de modifications possible ?

Merci pour vos conseils !

大家讲道理
大家讲道理

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

répondre à tous(2)
大家讲道理
  1. fs.stat est une opération asynchrone, donc les informations de votre fichier de sortie sont exécutées de manière asynchrone et "sortie terminée" doit être imprimée en premier. Si vous souhaitez synchroniser, vous pouvez utiliser ceci https://nodejs.org/docs/lates...

  2. Ajouter un console.log('sleep') pour dormir pour voir s'il ne sort qu'une seule fois ?

  3. Si vous souhaitez vous assurer que la "sortie terminée" n'est affichée qu'après la sortie des informations du fichier, le fs.statSync que j'ai mentionné dans le premier point nécessite probablement moins de modifications

Ty80

Selon la réponse de @Dont, c'est en effet la raison de l'appel de méthode asynchrone, car la fonction de rappel de fs.stat est appelée lors de l'interrogation d'événements. Elle est généralement appelée pendant l'intervalle entre l'exécution du programme principal et l'heure. et l'ordre d'appel sont incertains. La synchronisation peut être réalisée à l'aide de la méthode statSync :

(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++;
    ................
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal