web-dev-qa-db-fra.com

array.length est à zéro, mais le tableau contient des éléments

Je suis actuellement en train de me servir d'électron, mais javascript est une nouveauté et j'ai rencontré un problème qui me laisse complètement perplexe. J'ai le code suivant:

    function getPaths() {
      var dirPath = document.getElementById("mdir").innerHTML;
      var filePaths = [];
      fs.readdir(dirPath, function(err, dir) {
        for(var i = 0, l = dir.length; i < l; i++) {
          var filePath = dir[i];
          filePaths.Push(dirPath + "/" + filePath);
        }
      });
      console.log(filePaths);
      console.log(filePaths.length);
    }

Ce qui est supposé examiner un répertoire défini par dirPath, puis effectue une boucle et obtient le chemin complet de tous les fichiers de ce répertoire. Il les ajoute à un tableau, puis en bas, il enregistre le tableau dans la console, suivi de la longueur du tableau . Ce qui me déconcerte, c'est que, étant donné ce code, le tableau se connecte à la console comme prévu , mais la console enregistre zéro comme longueur. Ma pensée actuelle est que cela a quelque chose à voir avec la portée, mais cela n’a aucun sens car je déclare le tableau, filePaths, dans la fonction située au-dessus de celle qui est en cours d’exécution. Sauf si j'ai raté quelque chose. Quelqu'un pourrait-il indiquer ce que je fais mal?

8
Taira

readdir est asynchrone. Le résultat ne sera pas obtenu tout de suite. Vous devez consigner la filePaths à l'intérieur du rappel. La console affiche la valeur uniquement parce qu'elle évalue le tableau lorsque vous le dépliez.

Lorsque vous appuyez sur la petite flèche à gauche, placez la souris sur la case i à droite. En réalité, la console garde une référence sur le tableau. Ainsi, lorsque l'utilisateur déplie le tableau, il affiche sa valeur actuelle. Mais lorsque vous enregistrez filePaths.length, le tableau est vide car readdir n'a pas encore fini de lire, c'est pourquoi vous obtenez 0. Mais au moment où vous ouvrez la console et appuyez sur cette flèche, readdir sera déjà terminé et la console affichera la valeur actuelle. du tableau (après qu'il ait été rempli).

 enter image description here

Exemple pour démontrer le problème: (pas une solution, c'est juste pour comprendre ce qui se passe réellement)

Essayez d’exécuter ce code et voyez ce qui se passe:

var arr = [];
setTimeout(function() {
  arr.Push(1, 2, 3);
}, 5000);
console.log(arr.length);
console.log(arr);

Ici, le tableau et sa longueur sont tous deux consignés avant que le tableau ne soit rempli. Le tableau sera rempli après 5 secondes. Donc, le résultat sera 0 et une chaîne array[]. Les tableaux pouvant contenir des tonnes de données, la console n'affiche pas ces données jusqu'à ce que l'utilisateur déplie le tableau. La console conserve donc une référence au tableau jusqu'à ce que l'utilisateur clique sur la flèche de dépliage. Si vous déployez le tableau avant 5 secondes, vous voyez qu'il est vide (pas encore rempli). Si vous attendez jusqu'à ce que les 5 secondes se soient écoulées, que vous le dépliiez, vous verrez qu'il est rempli.

Remarque: De plus, la ligne qui est enregistrée dans la console (quelque chose comme > Array(0)) est simplement une représentation sous forme de chaîne de l'objet/du tableau au moment où le journal se produit. Il ne sera pas mis à jour si l'objet/le tableau change. Donc, cela peut aussi sembler déroutant parfois.

J'espère que c'est clair maintenant.

10
ibrahim mahrir

Juste pour développer la réponse de @ ibrahim-mahrir, ils signifient comme ceci

function getPaths() {
    var dirPath = document.getElementById("mdir").innerHTML;
    var filePaths = [];
    fs.readdir(dirPath, function(err, dir) {
        for (var i = 0, l = dir.length; i < l; i++) {
            var filePath = dir[i];
            filePaths.Push(dirPath + "/" + filePath);
        }
        console.log(filePaths);
        console.log(filePaths.length);
    });
}
1
Jeremy Jackson