我在从node.js中的回调函数返回值时遇到了小麻烦,我将尽量简单地解释我的情况。假设我有一个代码片段,它获取URL并点击该URL并给出输出:
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
});
我试着将它包装在函数中,并返回如下所示的值:
function doCall(urlToCall) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
因为在我的node.js代码中,我有很多if-else
语句,其中将决定URLToCall
的值,如下所示:
if(//somecondition) {
urlToCall = //Url1;
} else if(//someother condition) {
urlToCall = //Url2;
} else {
urlToCall = //Url3;
}
问题是urllib.request
中的所有语句将保持不变,除了urlToCall
的值。所以我肯定需要把这些公共代码放在一个函数中。我尝试了同样的方法,但是在docall
中,将始终返回undefined
。我这样试过:
response = doCall(urlToCall);
console.log(response) //Prints undefined
但是如果我在docall()
内打印值,它会完美地打印,但是它总是返回undefined
。根据我的研究,我知道我们不能从回调函数返回值!(是真的吗)?如果是,有没有人可以建议我如何处理这种情况,因为我希望在每个if-else
块中防止重复代码。
它的未定义
,因为console.log(response)
在docall(urlToCall);
完成之前运行。您还必须传入一个回调函数,该函数在您的请求完成时运行。
第一,你的功能。传递回调:
function doCall(urlToCall, callback) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return callback(finalData);
});
}
现在:
var urlToCall = "http://myUrlToCall";
doCall(urlToCall, function(response){
// Here you have access to your variable
console.log(response);
})
@Rodrigo,在评论里发了一个不错的资源。阅读node中的回调及其工作原理。记住,它是异步代码。
我在从node.js中的回调函数返回值时遇到了小麻烦。
这并不是一个“小麻烦”,从一个异步函数中“返回”一个传统意义上的值实际上是不可能的。
因为您不能“返回值”,所以您必须调用一旦有了该值就需要该值的函数。@display_name已经回答了您的问题,但我只想指出doCall中的返回并不是以传统的方式返回值。您可以按如下方式编写doCall:
function doCall(urlToCall, callback) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
// call the function that needs the value
callback(finalData);
// we are done
return;
});
}
行回调(finalData);
调用需要从异步函数获得值的函数。但要注意,return语句用于指示函数在此结束,但并不意味着值返回给调用方(调用方已经继续前进。)
node.js-async函数到sync函数的示例代码:
var deasync = require('deasync');
function syncFunc()
{
var ret = null;
asyncFunc(function(err, result){
ret = {err : err, result : result}
});
while((ret == null))
{
deasync.runLoopOnce();
}
return (ret.err || ret.result);
}