2017-02-27 86 views
0

我在下面有一些代碼將返回某個目錄中的某些鍵和值的所有文件。我想要的其中一個鍵是具有布爾值的isDirectory。節點Promise返回對象的值爲已解決的承諾

下面的代碼工作得很好,但我想知道是否有辦法刪除Promise.all /迭代承諾,而是直接在我的地圖中將解析值stat.isDirectory()推送到我的文件對象。

我的解決辦法我試過,但失敗:

我想是這樣的:

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

然後做一個Promise.all上的所有isDirectory

工作代碼:

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部分?而是在我的地圖中執行這些操作?

回答

0

假設你正在使用最新的節點 - 你可以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; 
1

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