[英]Async functions in Node.js module
我是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現在會像這樣:
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
我的問題現在是,即使myFunction2()首先完成,myFunction1()總是在myFunction2()之前記錄。 我是否了解有關Promises的問題? 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);
});
在您的情況下,使用回調是最簡單的解決方案,但是您應該意識到還有其他模式可以處理異步執行。 這是一個很好的概述 。 例如,一種流行的解決方案是使用promises ,這在您必須鏈接異步延續時特別有趣,它可以允許
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);
})
首先,我建議您處理模塊中的錯誤( err
, stderr
)。 如您所見,您的函數采用一個參數,即回調。 如果您的異步函數運行,則調用回調函數。 因此,您可以像這樣使用它:
module.myFunction1(function(stdout) {
console.log("Output myFunction1: " + stdout);
module.myFunction2(function(stdout2) {
console.log("Output myFunction2: " + stdout2);
});
});
exec
函數還接受回調函數(第一個參數錯誤err
錯誤的第一個回調)。 還有其他方法可以處理異步代碼的流控制(例如,庫async )。 您還可以了解Promises ,它是今天的錯誤優先回調的替代方法。
回調函數不會直接返回值...您需要的是設置讀取值時將發生的情況。 像這樣:
my_function(what_will_happen_when_my_function_will_get_finished());
exectly:
myFunction1(function(data){console.log('hello! I've finished, and received: '+data);});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.