方案
需要并行运行两个任务,并完成firstTask && secondTask
之后的第三个任务。一直在使用async
库,并且代码有效,但是想知道我是否可以改进我的代码。
详细信息
任务1:readFileNames
:读取文件夹并返回文件名。
任务2:copyFile
:将config
文件从SRC文件夹复制到目标文件夹。
任务3:writeConfig
:将readFileNames
的结果写入位于destination
文件夹的config
文件。
问题
我应该将parallel
控制流与eachSync
相结合吗?另外,想知道承诺是否会帮助我实现自己的目标?哪种方法在性能方面更好?异步与Q,或者我应该使用更抽象的库,例如orchestrator
?
以下是我到目前为止的工作,它有效,但想知道是否有更好的方法:
代码
var async = require("async");
var fs = require("fs-extra");
var dir = require("node-dir");
var path = require("path");
var _ = require("underscore");
var readFileNames = function (src, cb) {
dir.files(src, function (err, files) {
if (err) { return cb(err); }
return cb(files);
});
};
var copyFile = function (src, dest, cb) {
fs.copy(src, dest, function (err) {
if (err) { return cb(err); }
return cb();
});
};
var writeConfig = function (destFile, content, cb) {
fs.appendFile(destFile, content, function (err) {
if (err) { return cb(err); }
return cb();
});
};
var modulesFolder = path.join(__dirname, "modules");
var srcFile = path.join(__dirname, "src", "config.json");
var destFile = path.join(__dirname, "dest", "config.json");
async.parallel(
[
function (callback) {
readFileNames(modulesFolder, function (files) {
callback(null, files);
});
},
function (callback) {
copyFile(srcFile, destFile, function () {
callback(null, "");
});
}
],
// last callback
function (err, results) {
var toWrite = _.flatten(results);
toWrite.forEach(function (content) {
if(content) {
writeConfig(destFile, content + "n", function () {
});
}
});
console.log("done");
}
);
文件
├── dest
├── main.js
├── modules
│ ├── module1.txt
│ └── module2.txt
├── node_modules
│ ├── async
│ ├── fs-extra
│ └── node-dir
├── package.json
└── src
└── config.json
我一直在使用异步库,并且代码有效,但是想知道我是否可以改进我的代码。
您正在使用太多匿名函数表达式。只需通过您要收到的callback
即可!所有这些辅助功能(包括指定的功能)都是多余的。
另外,您的readFileNames
功能不遵循节点回调约定。我认为您不打算将错误写入结果文件?
您的最终回调确实忽略了错误。
我应该将平行控制流与每个sync结合在一起?
我想你是说eachSeries
,而不是eachSync
?是的,如果您期望appendFile
打电话给链条,那将是合理的。但是,您可以再次使用parallel
,这将与您当前正在做的.forEach
更紧密相关。但是,如果您应该使用async
迭代方法,因为当前您还为时过早记录"done"
。
所以做
var async = require("async");
var fs = require("fs-extra");
var dir = require("node-dir");
var path = require("path");
var modulesFolder = path.join(__dirname, "modules");
var srcFile = path.join(__dirname, "src", "config.json");
var destFile = path.join(__dirname, "dest", "config.json");
async.parallel([
function (callback) {
dir.files(modulesFolder, callback);
},
function (callback) {
fs.copy(srcFile, destFile, callback);
}
], function(err, results) {
if (err)
return console.error(err);
var toWrite = results[0] // ignore the result of the copy action
async.eachSeries(toWrite, function(content, callback) {
// if(content) not sure if needed at all
fs.appendFile(destFile, content + "n", callback);
}, function(err) {
if (err)
return console.error(err);
console.log("done");
});
});
另外,想知道承诺是否会帮助我实现自己想做的事情?
是的,他们也可以做到这一点,甚至可能更容易,更直接(如果您习惯了)。他们还可以简化错误处理。
哪种方法在性能方面更好?
都不。这个小脚本的性能受您系统的IO功能的限制,以及您的算法使用的并行程度。这两个库都可以实现。
您对async.parallel()
的使用对我来说看起来不错,如果完成工作,就完成了。关于性能,您是否并行所有可以并行完成的任务?您的磁盘io速度有多快?这些问题比您选择的异步/保证图书馆的选择重要。
话虽如此,与异步相比,像Q这样的承诺库通常会稍微下降一点,因为它们往往会在没有严格必要的情况下执行process.nextTick
,但是这种性能降级很小。在绝大多数情况下,绩效问题不应决定您选择异步/承诺库。