I'm kind of new to JavaScript/Node.js so bear with me. Also my english may not be that good.
I'm trying to write a Node.js module module.js with functions that do some long-running work. Kind of like this:
var exec = require('child_process').exec;
module.exports.myFunction1 = function(callback) {
// this function runs for like 3 seconds
exec('long running shell command' ,function(err,stdout,stderr) {
callback(stdout);
})
};
module.exports.myFunction2 = function(callback) {
// this function runs for like 1 second
exec('long running shell command' ,function(err,stdout,stderr) {
callback(stdout);
})
};
Now, I also have a main.js where I invoke these functions:
var module = require('./module.js');
var output1 = module.myFunction1();
var output2 = module.myFunction2();
My first problem is that my functions return undefined. I understand that this is because the exec function runs asynchronously and therefore the function returns before exec has finished. This is basically what I want but how can I tell my function that it should only callback when exec has finished?
I also don't want the functions to block node.js when I invoke them in my main.js. So basically, my output of the above code would be...
Output myFunction2: Output2
Output myFunction1: Output1
...because myFunction2() finishes faster than myFunction1().
I tried many, many solutions I found online but nothing seems to work properly.
Thank you very much in advance!
--- EDIT ---
Ok, I'm having a somewhat correct solution. Right now my code looks like this:
module.js
var Q = require('q');
require('shelljs/global')
module.exports = {
myFunction1: function () {
var deferred = Q.defer();
var result = exec('long running command', {silent:true}).output.toString();
if (ok) {
deferred.resolve(result);
}
else {
deferred.reject('Error');
}
return deferred.promise;
},
myFunction2: function () {
var deferred = Q.defer();
var result = exec('long running command', {silent:true}).output.toString();
if (ok) {
deferred.resolve(result);
}
else {
deferred.reject('Error');
}
return deferred.promise;
}
}
My main.js lloks like this now:
var module = require('./module');
module.myFunction1()
.then(function (result) {
console.log('Result 1: ' + result);
})
.fail(function (error) {
console.log(error)
});
module.myFunction2()
.then(function (result) {
console.log('Result 2: ' + result);
})
.fail(function (error) {
console.log(error)
});
And I get the expected output:
Result 1: Output that myFunction1() generated
Result 2: Output that myFunction2() generated
My Problem now is, that myFunction1() always logs before myFunction2(), even if myFunction2() finished first. Did I understood something wrong about Promises? Shouldn't myFunction2() return immediately after it finished?