2017-02-27 1 views
0

특정 키와 값이있는 디렉토리의 모든 파일을 반환하는 일부 코드가 있습니다. 내가 원하는 키 중 하나는 부울 값을 가진 디렉토리입니다.노드 확정 된 값을 가진 약속 반환 객체

아래의 코드는 정상적으로 작동하지만 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 부분을 제거 할 수 있습니까? 대신 내지도에서 이러한 작업을 수행 하시겠습니까? 모든 파일이 끝날 때까지 대기 할 때문에

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; 

답변

0

최신 노드를 사용하는 가정이 async/await 수는 함수 정의하기 전에 async을 넣고 할 최종 결과를 사용하기 전에 하지만 하나의 전화로 모든 것을 할 수 있습니다. .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

당신은, 완전히 Promise.all를 제거 할 수 없습니다 : -