我是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();
我的第一个问题是我的函数返回 undefined 。我知道这是因为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 lloks现在这样:
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()先完成。我对Promises有什么不妥吗?完成后myFunction2()不应该立即返回吗?
答案 0 :(得分:1)
您的功能需要回调。这些参数是在完成时调用的函数,这使得它很容易实现
struct task_struct *task;
struct list_head *list;
list_for_each(list, ¤t->children) {
task = list_entry(list, struct task_struct, sibling); /* task now points to one of current’s children */
}
在您的情况下,使用回调是最简单的解决方案,但您应该知道还有其他模式可以处理异步执行。这是a good overview。例如,一个流行的解决方案,特别是当你必须链接异步延续时很有意思的是使用 promises ,这允许
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);
});
答案 1 :(得分:0)
首先,我建议您在模块中处理错误(err
,stderr
)。如您所见,您的函数采用一个参数即回调。如果您的异步函数运行,则调用回调函数。所以你可以像这样使用它:
module.myFunction1(function(stdout) {
console.log("Output myFunction1: " + stdout);
module.myFunction2(function(stdout2) {
console.log("Output myFunction2: " + stdout2);
});
});
exec
函数也接受回调函数(第一个参数错误err
- 错误第一个回调)。如何处理异步代码的流控制还有其他选择(例如库async)。您还可以了解Promises,它是今天错误优先回调的替代方法。
答案 2 :(得分:0)
回调函数不会直接返回值...您需要的是设置读取值时会发生什么。像这样:
my_function(what_will_happen_when_my_function_will_get_finished());
exectly:
myFunction1(function(data){console.log('hello! I've finished, and received: '+data);});