array.length为零,但数组中包含元素

Tai*_*ira 10 javascript arrays scope electron

我目前正在练习使用电子,但我对javascript很新,我遇到了一个让我感到困惑的问题.我有以下代码:

    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);
    }
Run Code Online (Sandbox Code Playgroud)

应该查看定义的目录dirPath,然后循环并获取该目录中所有文件的完整路径.它将它们附加到一个数组,然后在底部,它将数组记录到控制台,然后是数组的长度.令我感到困惑的是,给定该代码,数组会按预期记录到控制台,但随后控制台将长度记录为零.我目前的想法是它与范围有关,但这没有意义,因为我在filePaths正在运行的函数之上的函数中声明了数组.除非我错过了什么.谁能指出我做错了什么?

ibr*_*rir 15

readdir是异步的.它不会马上得到结果.你应该记录filePaths回调内部.控制台显示值的唯一原因是控制台在展开时评估数组.

当您按左侧的小箭头时,将鼠标放在i右侧的框中.发生的事情是控制台保留对数组的引用,因此当用户展开数组时,它会显示其当前值.但是当你记录filePaths.length数组是空的,因为readdir没有完成阅读,这就是为什么你得到0.但是当你打开控制台并按下那个箭头时,readdir已经完成阅读,控制台将打印数组的当前值(填写完毕后).

在此输入图像描述

举例说明问题:(不是解决方案,只是要了解真正发生的事情)

尝试并运行此代码,看看发生了什么:

var arr = [];
setTimeout(function() {
  arr.push(1, 2, 3);
}, 5000);
console.log(arr.length);
console.log(arr);
Run Code Online (Sandbox Code Playgroud)

这里数组及其长度都在数组填充之前记录.阵列将在5秒后填满.所以输出将是0一个字符串array[].现在因为数组可能有大量数据,控制台不会显示数据,直到用户展开数组.所以控制台所做的是保持对阵列的引用,直到用户按下展开箭头.如果在5秒之前展开数组,则会看到数组为空(尚未填充).如果你等到5秒钟过去然后展开它,那么你会看到它被填满了.

注意:此外,记录到控制台的行(类似> Array(0))只是日志发生时对象/数组的字符串表示.如果对象/数组发生更改,它将不会更新.所以有时也可能会让人感到困惑.

我希望现在很清楚.

  • 我不建议使用 `setTimeout` 函数,因为响应时间可能会因目录内容而异 (2认同)
  • @MaxZoom我没有建议`setTimeout`作为解决方案!我刚刚使用一个易于理解的例子使用`setTimeout`来解释OP的问题,以强调问题的异步性! (2认同)
  • 好的,所以如果我做对了,我没有得到值的原因是因为 readdir 是异步的。因此,console.log() 在数组构建之前完成,结果它返回 0? (2认同)