What is a clean way to use bluepird promisified fs
methods? readdir
will produce an array of files and folders, but if I in turn which to loop through the directories it provides, I end up writing something very similar to a callback nesting paradigm (except it doesn't even work). What is the standard practice chaining these promises in such a way that their return values may be looped through?
var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs-extra'));
var path = require('path');
var junk = require('junk');
//this does not work
fs.readdirAsync('./node_modules')
.bind(this)
.then((modules) => {
this.allFiles = [];
modules = modules.filter((item) => junk.not && !/^\./.test(item));
modules.forEach((module, index, modulesArray) => {
fs.readdirAsync(path.join('node_modules', module)) //ugly af and don't even get files to next `then`!
.then((files) => {
console.log(files); // yep, array of files all right
this.allFiles.push(files);
});
})
})
.then(() => {
console.log('all of the files', this.allFiles) // => [] no files 😞
})
.catch((err) => {
console.error('error! error!', err);
})
You aren't returning a promise in your first outer then
. Therefore your outer promise chain doesn't wait for the files to be read.
You can use Promise.all
+ map
to do so. A second suggestion from me is to don't use this
to store your values but pass all needed information through your promise chains. That makes the code much shorter:
fs.readdirAsync('./node_modules')
.then((modules) => {
return Promise.all(modules.filter((item) => junk.not && !/^\./.test(item))
.map(module => fs.readdirAsync(path.join('node_modules', module))));
})
.then(allFiles => {
console.log('all of the files', allFiles);
})
.catch((err) => {
console.error('error! error!', err);
});