2016-11-19 76 views
2

以下this snippet我想写一个循环槽目录,查找目录,并从这些目录中读取XML文件名的函数(我知道文件夹结构将始终保持相同)。到目前为止,我的函数按预期工作,但是当我试图从函数返回时,我只是得到Promise对象。蓝鸟 - 功能返回承诺对象,而不是实际数据

我的代码:

const Promise = require('bluebird'); 
const fs = Promise.promisifyAll(require('fs')); 
const path = require('path'); 

function getFileNames(rootPath) { 
    // Read content of path 
    return fs.readdirAsync(rootPath) 
    // For every file in path 
    .then(function(directories) { 
     // Filter out the directories 
     return directories.filter(function(file) { 
     return fs.statSync(path.join(rootPath, file)).isDirectory(); 
     }); 
    }) 
    // For every directory 
    .then(function(directories) { 
     return directories.map(function(directory) { 
     // Read file in the directory 
     return fs.readdirAsync(path.join(rootPath, directory)) 
      .filter(function(file) { 
      return path.extname(file) == '.XML'; 
      }) 
      .then(function(files) { 
      // Do something with the files 
      return files; 
      }); 
     }); 
    }); 
} 

getFileNames('./XML').then(function(files) { 
    console.log(files); 
}); 

当我console.log(files)getFileNames最后.then函数中,我得到的文件名的实际阵列控制台。但是,当我运行上面的代码我得到这样的输出:

[ Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined }, 
    Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined }, 
    Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined }, 
    Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined }, 
    Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined } ] 

为什么会出现这种情况,如何解决?

回答

2

在行

.then(function(directories) { 
    return directories.map(function(directory) { 
    return fs.readdirAsync… 

您正在创建的承诺数组的承诺,这就是你在你最终的日志得到什么。而不是返回承诺的数组,你需要返回一个承诺的值的数组 - 和Promise.all恰恰是什么:

.then(function(directories) { 
    return Promise.all(directories.map(function(directory) { 
    return fs.readdirAsync(…) 
    … 
    })); 
}) 

然而,在青鸟那将是更地道使用Promise.map(directories, function(…) { … })甚至the map method (类似于如何已经使用.filter在每个目录中的文件一样):

function getFileNames(rootPath) { 
    return fs.readdirAsync(rootPath) 
    .filter(function(file) { 
    return fs.statAsync(path.join(rootPath, file)).then(function(s) { 
     return s.isDirectory(); 
    }); 
    }) 
    .map(function(directory) { 
//^^^^ 
    return fs.readdirAsync(path.join(rootPath, directory)) 
    .filter(function(file) { 
     return path.extname(file) == '.XML'; 
    }) 
    .map(function(file) { 
     // Do something with every file 
     return file; 
    }); 
    }); 
} 
0

试试这个

return getFileNames('./XML').then(function(files) { 
    console.log(files); 
    return files; 
}); 
+0

stil得到相同的输出 –

+0

@MihaŠušteršič我编辑answer – stasovlas

0

这段代码:

.then(function(directories) { 
    return directories.map(function(directory) { 
    return fs.readdirAsync(path.join(rootPath, directory)) 
    ... 

将返回承诺的阵列,以当时的回调。承诺数组在这里被视为立即值,不会被集中到数组的承诺。为了承诺数组转换为可以使用Promise.all数组的一个承诺,但由于使用的是蓝鸟,你有更好的选择:

所有你所要做的就是用Promise.map

.then(function(directories) { 
    return Promise.map(directories, function(directory) { 
    return fs.readdirAsync(path.join(rootPath, directory)) 
    ... 
0

想通了,有一个。后来太上第二个功能:

const Promise = require('bluebird'); 
const fs = Promise.promisifyAll(require('fs')); 
const path = require('path'); 

function getFileNames(rootPath) { 
    // Read content of path 
    return fs.readdirAsync(rootPath) 
     .then(function(content) { 
     return content.filter(function(file) { 
      return fs.statSync(path.join(rootPath, file)).isDirectory(); 
     }); 
     }) 
     // For every directory 
     .map(function(directory) { 
     // Read files in the directory 
     return fs.readdirAsync(path.join(rootPath, directory)) 
      .filter(function(file) { 
       return path.extname(file) == '.XML'; 
      }); 
     }); 
} 

getFileNames('./XML').then(function(files) { 
    console.log(files); 
});