The primary difference here is execSync
which would be blocking and exec
would be non-blocking. execSync
blocks the creating process until the child_process created using execSync
returns. exec
immediately returns and will return a value if there is one later on and won't block the creating parent process. Otherwise, how they behave outside of the blocking is identical.
async.waterfall
is a control flow mechanism that just guarantees that operations are executed in order and chain return values from the first function in the chain to the last function in the chain. If one of the functions passed to async.waterfall
contains code that would be blocking then async.waterfall
would also be blocked. async.waterfall
doesn't make the guarantee that all code executed inside it will be async.
The use of child_process
means that this will be executed on a separate process and not on the main process being executed using node
. You shouldn't use child_process
for control flow as there is overhead associated with creating and destroying a new child process. Unless you're doing some CPU intensive tasks or have a need for a separate process you should avoid this.
If you want to execute things synchronously you can wrap all of your code in a try/catch
block but I would definitely say don't use child_process
for control flow.
From a performance perspective, both of these approaches are bad as they create a child_process but, exec()
would be better as it at least returns immediately to the creating process allowing other code to continue executing. Whenever blocking code is used in Node, you're eliminating the primary benefit of using Node. There are situations where blocking is necessary, like requiring modules, but in most scenarios there is a non-blocking alternative.
As an aside, if you're trying to copy a file you can use the fs
module and pipe the original file into a new file in a new destination with a new name. The below approach is async, and doesn't require any external dependencies or control flow library. Additionally, it should be more performant than any of the code you've implemented above.
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();
});
}