如果这是linux shell,我想做的是:
copy file1 tmp
rename tmp file2
我可以做瀑布
function copyFile(cb) {
child_process.exec('cp file1 tmp', function (error, stdout, stderr) {
......
});
}
async.waterfall([
copyFile,
renameFile
], function (error) {
if (error) {
//handle readFile error or processFile error here
}
});
或猜测我能做到
child_process.execSync('cp file1 tmp");
child_process.execSync('rename tmp file2');
请问有什么区别?例如表现?阻止? 非常感谢!
答案 0 :(得分:2)
这里的主要区别是execSync
,它会阻塞,exec
会阻塞。 execSync
阻止创建过程,直到使用execSync
创建的child_process返回。 exec
会立即返回并返回一个值(如果以后有一个值)并且不会阻止创建父进程。否则,它们在阻塞之外的行为方式是相同的。
async.waterfall
是一种控制流机制,它只保证操作按顺序执行,链返回值从链中的第一个函数到链中的最后一个函数。如果传递给async.waterfall
的其中一个函数包含阻塞的代码,那么async.waterfall
也将被阻止。 async.waterfall
并不保证在其中执行的所有代码都是异步的。
使用child_process
意味着这将在单独的进程上执行,而不是在使用node
执行的主进程上执行。您不应该使用child_process
来控制流,因为与创建和销毁新子进程相关的开销很大。除非您正在执行一些CPU密集型任务或需要单独的流程,否则应该避免这种情况。
如果你想同步执行某些事情,你可以将所有代码包装在try/catch
块中,但我肯定会说不要使用child_process
来控制流程。
从性能角度来看,这两种方法都很糟糕,因为它们创建了一个child_process但是exec()
会更好,因为它至少会立即返回到创建过程,从而允许其他代码继续执行。每当在Node中使用阻塞代码时,您就消除了使用Node的主要好处。在某些情况下需要阻塞,例如需要模块,但在大多数情况下,存在非阻塞替代方案。
另外,如果您尝试复制文件,可以使用fs
模块并将原始文件通过新名称传输到新目标中的新文件中。以下方法是异步的,并且不需要任何外部依赖项或控制流库。此外,它应该比您在上面实现的任何代码更高效。
var fs = require('fs');
function copy (src, dest, callback) {
var r = fs.createReadStream(src);
var w = fs.createWriteStream(dest);
r.pipe(w);
r.on('error', function() {
return callback(err);
});
r.once('end', function() {
return callback();
});
}