arrays - 对数组进行排序会返回无序数组

标签 arrays node.js sorting promise fs

我现在很困惑。我花了最后一个小时尝试根据目录的创建日期对目录进行排序。这是我所在的位置:

const
  fsPromises = require('fs').promises
let
  arr = []

fsPromises.readdir(rootPath, 'utf8')
.then((array)=>{

  array.forEach((dir)=>{
    console.log(dir) // executed last for some reason
    fsPromises.stat(`./Projects/${dir}`)
    .then((stats)=>{
      arr.push([stats.birthtimeMs, dir])
    })
  })

})
.then(()=>{
  arr = arr.sort((a,b)=>{
    Math.floor(a[0])-Math.floor(b[0])
  })
})
.then(console.log(arr))

我不知道为什么最后的 then 会输出一个无序数组。

Promise 对我来说是新事物,所以我不完全确定是否是 Promise 链导致了问题,但在第二个 then 之前一切似乎都很好。

任何帮助将不胜感激。

最佳答案

这是 promise 链:如果链在任何地方被破坏,它就不会工作。

您似乎混淆了两种箭头形式:(params) => 表达式(params) => { statements }。代码中的所有内容都可以用前者来表达,所以我就这么做了。如果转换为语句 block 形式,请不要忘记return(表达式形式隐式执行此操作)。

因为您没有从箭头语句 block 返回 promise ,所以下一个 promise 不会与前一个 promise 缝合,因此不会发生等待,并且事情的执行比预期更加同步。此外,如果您有多个 Promise,则需要等待它们全部准备好使用 Promise.all 来实现。它将创建一个所有子 promise 都已完成的 promise ,并返回子 promise 结果的数组。

fsPromises.readdir(rootPath, 'utf8')
.then(array => Promise.all(
    array.map(dir =>
        fsPromises.stat(`./Projects/${dir}`)
        .then(stats => [stats.birthtimeMs, dir])
    )
))
.then(arr =>
  arr.sort((a, b) =>
    Math.floor(a[0]) - Math.floor(b[0])
  )
)
.then(arr => console.log(arr))

(我没有检查这一点,所以可能会有意外的龙。)

所以首先 readdir promise 一个文件数组。我们将映射这个数组,以便对于每个文件名,stat 对其统计数据做出 promise ,并将其链接到元组的 promise 中。因此 array.map 现在返回一个元组 Promise 数组。 Promise.all 接收 Promise 数组,并在这些 Promise 全部完成时 promise 一组结果。我们将其链接到排序数组的 promise 中,然后将其链接到控制台记录数组的 promise 中。

编辑:我不确定,但我不认为 Promise.all 存在于 Node.js 核心中。 Node.js 有很多 Promise 包都包含 Promise.all,几乎任何一个都可以(例如 Bluebird )。或者,您可以implement it yourself ,没那么大。

EDIT2:如果您的环境支持,也可能建议您切换到 async/await,因为它使代码与您习惯的代码更加相似。然而,仍然需要对 Promise 有一定的了解,因为所有的 Promise 都在幕后。 :P

async function statDir() {
  let files = await fsPromises.readdir(rootPath, 'utf8');
  let stats = [];
  for (let file of files) {
    let stat = await fsPromises.stat(`./Projects/${file}`);
    stats.push([stat.birthtimeMs, file]);
  }
  stats.sort((a, b) =>
    Math.floor(a[0]) - Math.floor(b[0])
  );
  console.log(stats);
}
statDir();

关于arrays - 对数组进行排序会返回无序数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58263740/

相关文章:

node.js - 尝试发出 POST 请求来注册新用户时出现 404 错误

javascript - 在 Azure 门户上运行 nodejs Cron 作业脚本

arrays - VBA:根据另一个数组对数组进行排序

javascript - 当 JavaScript 中的 forEach 或循环提供值时,条件执行

javascript - 启动 Node 应用程序时出错 - MEAN Stack

java - 按运行时间对歌曲集合进行排序

java - Java 迭代器或增强循环是否按创建顺序保证结果?

javascript - 使用 jquery 创建按钮来打开和关闭数据子组 - 来自数据数组

php - 将数据库信息存储为数组

java - 当我点击<<按钮时;它给出了 ArrayIndexOutOfBounds 异常