Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodeJS: chaining exec commands with promises

I am using nodeJS in order to chain two exec calls. I want to wait for the first one to finish and after that proceed with the second one. I am using Q for that.

My implementation looks like this:

I have an executeCommand function:

executeCommand: function(command) {
    console.log(command);
    var defer = Q.defer();
    var exec = require('child_process').exec;

        exec(command, null, function(error, stdout, stderr) {
            console.log('ready ' + command);
            return error 
                ? defer.reject(stderr + new Error(error.stack || error))
                : defer.resolve(stdout);
        })

        return defer.promise;
}

And a captureScreenshot function that chains two calls of the former one.

captureScreenshot: function(app_name, path) {
        return this.executeCommand('open -a ' + app_name)
            .then(this.executeCommand('screencapture ' + path));
}

When I execute captureScreenshot('sublime', './sublime.png) the logging output is as follows:

open -a sublime
screencapture ./sublime.png
ready with open -a sublime
ready with screencapture ./sublime.png

Can somebody explain why the execution of the second command (screencapture) is not waited for until the execution of the first command (open -a sublime) is finished? Of course I don't get a screenshot of the application I wanted to switch to because the screencapture command is being executed too early.

I though that was the whole point of promises and .then-chaining..

I would have expected this to happen:

open -a sublime
ready with open -a sublime
screencapture ./sublime.png
ready with screencapture ./sublime.png
like image 832
Schnodderbalken Avatar asked Aug 12 '26 13:08

Schnodderbalken


1 Answers

Therein lies your problem:

return this.executeCommand('open -a ' + app_name)
   .then(this.executeCommand('screencapture ' + path));

You've basically executed this.executeCommand('sreencapture'...), when, in fact, you actually wanted to defer it's execution when the previous promise resolved.

Try rewriting it as so:

return this.executeCommand('open -a ' + app_name)
    .then((function () { 
        return this.executeCommand('screencapture ' + path);     
     }).bind(this));
like image 114
Filip Dupanović Avatar answered Aug 14 '26 11:08

Filip Dupanović



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!