【发布时间】:2014-05-12 04:46:36
【问题描述】:
我正在尝试将文件返回到具有最早修改日期的目录中。这种方法在 createFileDateMap 函数中似乎失败了。我想减少一组文件路径并使用文件名和修改日期创建一个对象。 getModDate 函数是一个异步 fs.lstat 调用。我似乎无法将减速器的 acc 设置为 .then() 块中的值。当值依赖于异步调用时,我不确定如何实现减少
var _ = require('lodash'),
fs = require('fs'),
path = require('path'),
Q = require('q');
function checkDir(dir) {
// Check if given path is valid directory
var deferred = Q.defer();
fs.lstat(dir, deferred.makeNodeResolver());
return deferred.promise.invoke('isDirectory');
}
function getFiles(dir) {
// Get all files within a directory
var deferred = Q.defer();
fs.readdir(dir, deferred.makeNodeResolver());
return deferred.promise;
}
function makeFullPathFileArr(dir, files) {
// Return array of full paths
return _.map(files, function(file) {
return path.join(dir, file);
});
}
function getModDate(file) {
// Return modification date of file
var deferred = Q.defer();
fs.stat(file, deferred.makeNodeResolver());
return deferred.promise.get('mtime');
}
function createFileDateMap(filesArr) {
// Return an obj of file paths and modification dates as Date objects
// {{ file1: Date, file2: Date }}
var fileDateMap = _.reduce(filesArr, function(acc, file) {
getModDate(file)
.then(function(modDate) {
acc[file] = moment(modDate);
});
return acc;
}, {});
return fileDateMap;
}
function getMinDateFile(mapObj) {
// return the file name which has the earliest modification date
var dates = _.transform(mapObj, function(result, date, key) {
result[key] = new Date(date);
});
var minDate = new Date(Math.min.apply(null, _.values(dates)));
var invertedMapObj = _.invert(mapObj);
return invertedMapObj[minDate];
}
var dir = '../reports';
checkDir(dir)
.then(function(exist) {
if(exist) {
getFiles(dir)
.then(function(fileNames) {
return makeFullPathFileArr(dir, fileNames);
})
.then(function(fullpathsArr) {
return createFileDateMap(fullpathsArr);
})
.then(function(fileAndDatesObj) {
console.log(getMinDateFile(fileAndDatesObj));
});
}
})
.catch(function(err) {
console.log(err);
});
【问题讨论】:
-
顺便说一句,看看
Q.ninvoke()或Q.nfbind()。 -
你没有从 reduce 函数返回。那是你的错误。此外,正确地承诺您的 API(如 SLaks 建议的)可以真正帮助您编写代码。
-
我正在浏览 Q 文档。我将如何使用这些方法?我认为在这里使用 makeNodeResolver() 更合适。
-
在您最近的编辑之后,您的退货声明仍然是错误的。您需要从减少返回,而不是从
.then。您确定您不只是在寻找等待一系列承诺全部解决的Q.all吗?Q.all(filesArr.map(getModDate)).then(function(files){... -
@Ptrkcon 请不要将答案编辑到问题中,将问题保留在初始修订版中 - 否则作为问题毫无意义。至于手动承诺 API,风险更大,因为承诺是安全抛出的(它们的一大优势)并且具有合理的异常处理 - 这要求返回承诺的函数也不会同步抛出(而是返回被拒绝的承诺) - 很多时候人们在将回调 API 转换为 Promise 时会错过更微妙的地方,尤其是对于延迟对象。
标签: javascript node.js promise q lodash