I am writing attempting to write a function that accomplishes the same as the following written using a callback pattern with a promise pattern:
function readdirRecursive(path,handler,callback) {
var errs = [],
tree = {};
fs.readdir(path,function(err,dir) {
if(err)return callback(err);
var pending = dir.length;
if(!pending)return callback(null,tree);
dir.forEach(function(file) {
var newPath = Path.join(path,file);
fs.stat(newPath,function(err,stats) {
if(stats.isDirectory()) {
readdirRecursive(newPath,handler,function(err,subtree) {
tree[file] = subtree
handler(tree,newPath,file,"directory",function(err) {
if(err)errs.push(err);
if(!--pending)return callback(errs.length>0?errs:null,tree);
});
});
} else {
tree[file] = null;
handler(tree,newPath,file,"file",function(err) {
if(err)errs.push(err);
if(!--pending)return callback(errs.length>0?errs:null,tree);
});
}
});
});
});
};
this is my current attempt:
function readdirRecursive(path) {
var tree = {};
return Q.Promise(function(resolve,reject,notify) {
return readdir(path)
.then(function(dir) {
var futures = [];
var pending = dir.length;
if(!pending)return resolve(tree);
dir.forEach(function(file) {
var deferred = Q.defer();
var subPath = Path.join(path,file);
futures.push(stat(subPath)
.then(function(stats) {
if(stats.isDirectory()) {
tree[file] = tree;
var sub = readdirRecursive(subPath)
sub
.then(function(subtree) {
notify({
path:subPath,
name:file,
type:"directory",
done:deferred,
pending:pending
});
//return subtree;
},reject,notify);
} else {
tree[file] = null;
notify({
tree:tree,
path:subPath,
name:file,
type:"file",
done:deferred,
pending:pending
});
//return null;
}
//console.log("tree",tree);
deferred.promise()
.then(function() {
console.log("pending promise");
if(!--pending)resolve(tree);
}
,function(err) {
reject();
});
}));
});
return Q.all(futures)
.then(function(futures) {
console.log("hi",futures);
});
});
});
};
This code will iterate over the entire tree, but it will not return a tree, and the the notification action occurs, but the deferred promise does not ever resolve.
When the deferred promise is initiated before the notify event, nothing happens at all.
I know that I could solve this problem by handing a done function to the progress event instead of attempting to give a promise of some sort, but I want to make as full of use of promises here as possible, for example, this code does exactly what I want it to do:
function readdirRecursive(path) {
var tree = {};
return Q.Promise(function(resolve,reject,notify) {
return readdir(path)
.then(function(dir) {
var futures = [];
var pending = dir.length;
if(!pending)return resolve(tree);
dir.forEach(function(file) {
var deferred = Q.defer();
var subPath = Path.join(path,file);
console.log("file",file);
/*deferred.promise()
.then(function() {
console.log("pending promise");
if(!--pending)resolve(tree);
}
,function(err) {
reject();
});*/
futures.push(stat(subPath)
.then(function(stats) {
if(stats.isDirectory()) {
var sub = readdirRecursive(subPath)
sub
.then(function(subtree) {
tree[file] = subtree
notify({
path:subPath,
name:file,
type:"directory",
done:function(err) {
console.log("pending promise");
if(err)return reject(err);
if(!--pending)resolve(tree);
},
pending:pending
});
//return subtree;
},reject,notify);
} else {
tree[file] = null;
notify({
tree:tree,
path:subPath,
name:file,
type:"file",
done:function(err) {
console.log("pending promise");
if(err)return reject();
if(!--pending)resolve(tree);
},
pending:pending
});
//return null;
}
//console.log("tree",tree);
}));
});
return Q.all(futures)
.then(function(futures) {
console.log("hi",futures);
});
});
});
};
this is the code that will be executing these functions:
readdirRecursive("../").then(function(tree) {
console.log("TREE!!!",tree);
},function(err) {
console.log("ERROR",err);
},function(progress) {
console.log("PRGRESS WAS MADE",progress);
progress.done();
});
.allthe array.