我对 JavaScript/Node.js 不太熟悉,所以请耐心等待。而且我的英语可能不太好。
我正在尝试编写一个 Node.js 模块 module.js ,其中包含执行一些长时间运行工作的函数。有点像这样:
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);
})
};
现在,我还有一个 main.js,我可以在其中调用这些函数:
var module = require('./module.js');
var output1 = module.myFunction1();
var output2 = module.myFunction2();
我的第一个问题是我的函数返回未定义。我知道这是因为 exec 函数异步运行,因此该函数在 exec 完成之前返回。这基本上就是我想要的,但是我如何告诉我的函数它应该只在 exec 完成时回调?
当我在 main.js 中调用这些函数时,我也不希望这些函数阻塞 node.js。所以基本上,我的上述代码的输出将是...
Output myFunction2: Output2
Output myFunction1: Output1
...因为 myFunction2() 比 myFunction1() 完成得更快。
我尝试了很多在网上找到的解决方案,但似乎都无法正常工作。
提前非常感谢您!
--- 编辑 ---
好的,我有一个稍微正确的解决方案。现在我的代码如下所示:
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;
}
}
我的main.js现在像这样:
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)
});
我得到了预期的输出:
Result 1: Output that myFunction1() generated
Result 2: Output that myFunction2() generated
我现在的问题是,myFunction1() 总是在 myFunction2() 之前记录,即使 myFunction2() 先完成也是如此。我对 Promise 的理解有误吗? myFunction2() 完成后不应该立即返回吗?
最佳答案
您的函数需要回调。这些参数是在完成时调用的函数,这使得它很容易做到
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.myFunction1(function(stdout){
console.log("Output myFunction1: " + stdout);
});
在您的情况下,使用回调是最简单的解决方案,但您应该意识到还有其他模式可以处理异步执行。这是a good overview 。例如,一个流行的解决方案,当您必须链接异步延续时特别有趣,是使用 promise ,它允许
var exec = require('child_process').exec;
module.exports.myFunction1 = function() {
return new Promise(function(resolve, fail){
// this function runs for like 3 seconds
exec('long running shell command' ,function(err,stdout,stderr) {
if (err) fail(err);
else resolve(stdout, stderr);
});
});
};
module.myFunction1()
.then(function(stdout){
console.log("Output myFunction1: " + stdout);
})
.then(module.myFunction2)
.then(function(stdout){
console.log("Output myFunction2: " + stdout);
})
关于javascript - Node.js 模块中的异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34704709/