簡體   English   中英

具有已解決的Promise值的Node Promise返回對象

[英]Node Promise return object with value of resolved promise

我下面有一些代碼,這些代碼將返回具有某些鍵和值的目錄中的所有文件。 我想成為的鍵之一是具有布爾值的isDirectory。

下面的代碼工作正常,但是我想知道是否有一種方法可以刪除Promise.all /迭代promise,而是將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部分? 而是在我的地圖中執行了這些操作?

您不能完全刪除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));

假設您使用的是最新的Node-您可以async/await ,將async放在函數定義之前,然后執行以下操作:

const fileNames = await fs.readdirAsync(desktopPath);
const files = await Promise.map(fileNames, fileName => Promise.props({
  path: `${desktopPath}/${fileName}`,
  name: fileName,
  ext: fileName.split('.').pop(),
  isDirectory: fs.statAsync(`${desktopPath}/${fileName}`);
})));
console.log(files);
return files;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM