Node.js nodeJS:在瀑布中运行一批childprocess命令
我试图优雅地一个接一个地运行五个git命令,同时保持捕获错误和进度的能力:Node.js nodeJS:在瀑布中运行一批childprocess命令,node.js,git,child-process,Node.js,Git,Child Process,我试图优雅地一个接一个地运行五个git命令,同时保持捕获错误和进度的能力: git状态 吉特拉力 git添加 git提交-am“提交消息” git推送 开源注释:我研究了不同的节点git库,出于不同的原因决定自己实现它 使用,我创建了一个延迟方法来运行子进程: var exec = require('child_process').exec, path = require('path'), Q = require('q'), gitPath = path.resolv
- git状态
- 吉特拉力
- git添加
- git提交-am“提交消息”
- git推送
var exec = require('child_process').exec,
path = require('path'),
Q = require('q'),
gitPath = path.resolve(__dirname + "/../projects/langs");
function run(command) {
var deferred = Q.defer();
exec(command, {cwd: gitPath}, function puts(error, stdout, stderr) {
if (error) {
deferred.reject(new Error(error));
} else {
deferred.resolve(stdout);
}
});
return deferred.promise;
}
但是,我想避免:
而且感觉不太优雅:
function options1a() {
// Pyramid of doom
run("git status").then(function (output) {
console.log(output);
run("git pull");
}).then(function (output) {
console.log(output);
run("git add .")
}).then(function (output) {
console.log(output);
});
}
我看到了第三种选择,但似乎无法实现:
function promiseWaterfall(tasks) {
var resolvedPromise = Q(undefined);
var finalTaskPromise = tasks.reduce(function (prevTaskPromise, task) {
return prevTaskPromise.then(task);
}, resolvedPromise); // initial value
return finalTaskPromise;
}
promiseWaterfall([
run("git status"),
run("git pull"),
run("git add .")
]).then(function () {
console.log(arguments);
});
我在玩第四个使用图书馆的选项:
但这似乎让我走上了一条没有承诺的道路
我如何让它优雅地工作?有什么最佳实践吗?我很熟悉,所以我将用promise库回答您的问题。它提供了类似于基于回调的异步库的帮助函数。更多的例子,请查看他们的网站
在下面的代码中,我使用when/sequence
模块来执行您要查找的内容。我还对您的代码组织进行了一些修改,使其保持模块化(例如,在您的示例中,没有将git-cwd嵌入run
函数中)
这是一个完全可以工作的实现。确保将git cwd更改为您自己的git存储库,因为它当前指向我自己的一个存储库
var exec=require('child_process')。exec
,when=require('when')
,sequence=require('when/sequence');
//exec的简单承诺包装器
函数执行(命令、选项){
选项=选项| |{};
var defer=when.defer();
exec(命令、选项、函数(错误、stdout、stderr){
返回错误
延迟.拒绝(stderr+新错误(Error.stack | | Error))
:延迟解析(标准输出);
});
回报、承诺;
}
//一些简单的git包装器
函数Git(config){
var self=这个;
self.config=config;
返回函数(gitCommand){
返回exec_p('git'+gitCommand,self.config);
};
}
//创建一个新的git指令并指定我们的选项
var git=new git({cwd://home/trev/git/tsenor});
//现在我们可以使用sequence&我们新创建的git包装器轻松地
//事情能一个接一个地井然有序吗
序列([
函数(){return git('status');},
函数(){return git('status');},
函数(){return git('status');},
函数(){return git('status');}
]).then(函数(结果){//在此处处理结果
控制台日志(结果);
})。否则(函数(错误){//在此处处理任何错误
console.error(error.stack | | error);
过程。退出(1);
});
提供的代码在每个步骤后都不会console.log
(它只是在最后注销结果),但是可以很容易地进行修改
function promiseWaterfall(tasks) {
var resolvedPromise = Q(undefined);
var finalTaskPromise = tasks.reduce(function (prevTaskPromise, task) {
return prevTaskPromise.then(task);
}, resolvedPromise); // initial value
return finalTaskPromise;
}
promiseWaterfall([
run("git status"),
run("git pull"),
run("git add .")
]).then(function () {
console.log(arguments);
});
async.waterfall([
function(callback){
callback(null, 'one', 'two');
},
function(arg1, arg2, callback){
callback(null, 'three');
},
function(arg1, callback){
// arg1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
// result now equals 'done'
});