Node Promise返回具有已解决的promise

时间:2017-02-27 15:16:35

标签: javascript node.js promise bluebird fs

我在下面有一些代码会返回包含某些键和值的目录中的所有文件。我想要的其中一个键是具有布尔值的目录。

下面的代码工作正常,但我想知道是否有办法删除Promise.all /迭代承诺,而是直接在我的地图中将stat.isDirectory()的已解析值推送到我的文件对象

我的解决方案我试过但失败了:

我试过这样的事情:

isDirectory: fs.statAsync(path).then((stat) => stat.isDirectory())

然后在所有isDirectory键上执行Promise.all

工作代码:

const Promise = require('bluebird'),
    os = require('os'),
    _ = require('lodash'),
    fs = Promise.promisifyAll(require('fs')),
    desktopPath = `${os.homedir()}/Desktop`;

let files = [];

return fs.readdirAsync(desktopPath)
    .then((filesName) => files = _.map(filesName, (fileName) => ({
        path: `${desktopPath}/${fileName}`,
        name: fileName,
        ext: _.last(fileName.split('.'))
    })))
    .then(() => Promise.all(_.map(files, (file) => fs.statAsync(file.path))))
    .then((stats) => _.forEach(stats, (stat, idx) => {
        files[idx].isDirectory = stat.isDirectory();
    }))
    .then(() => {
        console.log(files);
    })

最后是否要删除Promise.all和_.forEach部分?而是在我的地图中执行这些操作?

2 个答案:

答案 0 :(得分:2)

您无法完全删除Promise.all,因为您希望在使用最终结果之前等待所有文件完成。但是你可以通过一次.then()电话完成所有操作。

由于map是同步的,因此不会等待fs.statAsync完成。但是你可以创建一个fs.statAsync的承诺数组,用最终的文件对象解析,只需等待所有这些承诺使用Promise.all完成。

详细版本,附有一些注释要求澄清:

fs.readdirAsync(desktopPath)
  .then(fileNames => {
    // Array of promises for fs.statAsync
    const statPromises = fileNames.map(fileName => {
      const path = `${desktopPath}/${fileName}`;
      // Return the final file objects in the promise
      return fs.statAsync(path).then(stat => ({
        path,
        name: fileName,
        ext: _.last(fileName.split(".")),
        isDirectory: stat.isDirectory()
      }));
    });
    // Promise.all to wait for all files to finish
    return Promise.all(statPromises);
  })
  .then(finalFiles => console.log(finalFiles));

紧凑版:

fs.readdirAsync(desktopPath)
  .then(fileNames => Promise.all(
    fileNames.map(fileName =>
      fs.statAsync(`${desktopPath}/${fileName}`).then(stat => ({
        path: `${desktopPath}/${fileName}`,
        name: fileName,
        ext: _.last(fileName.split(".")),
        isDirectory: stat.isDirectory()
      })))
  ))
  .then(finalFiles => console.log(finalFiles));

答案 1 :(得分:1)

假设您正在使用最新的节点 - 您可以MyObject[] array = new [] { new MyObject { MyParam = "1" } }; Array.Resize(ref array, array.Length + 1); array[array.Length - 1] = new MyObject { MyParam = "2" }; ,将async/await放在您的功能定义之前并执行:

async