Javascript 从Node.js中的回调函数返回值
我在从Node.js中的回调函数返回值时遇到了小麻烦,我将尽可能简单地解释我的情况。考虑到我有一个片段,它使用URL并点击URL并给出输出:Javascript 从Node.js中的回调函数返回值,javascript,node.js,Javascript,Node.js,我在从Node.js中的回调函数返回值时遇到了小麻烦,我将尽可能简单地解释我的情况。考虑到我有一个片段,它使用URL并点击URL并给出输出: urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) { var statusCode = response.statusCode; finalData = getResponseJso
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;
});
}
if(//somecondition) {
urlToCall = //Url1;
} else if(//someother condition) {
urlToCall = //Url2;
} else {
urlToCall = //Url3;
}
response = doCall(urlToCall);
console.log(response) //Prints undefined
function doCall(urlToCall) {
return co(function *(){
var response = yield urllib.request(urlToCall, { wd: 'nodejs' }); // This is co-request.
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
因为在我的Node.js代码中,我有很多if-else
语句,其中urlToCall
的值将被确定,如下所示:
function doCall(urlToCall) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
if(//somecondition) {
urlToCall = //Url1;
} else if(//someother condition) {
urlToCall = //Url2;
} else {
urlToCall = //Url3;
}
response = doCall(urlToCall);
console.log(response) //Prints undefined
function doCall(urlToCall) {
return co(function *(){
var response = yield urllib.request(urlToCall, { wd: 'nodejs' }); // This is co-request.
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
问题是urllib中的所有语句。请求将保持不变,除了urlToCall
的值。所以我肯定需要把这些通用代码放在一个函数中。我尝试了相同的方法,但在doCall
中,将始终返回我未定义的。我试着这样做:
function doCall(urlToCall) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
if(//somecondition) {
urlToCall = //Url1;
} else if(//someother condition) {
urlToCall = //Url2;
} else {
urlToCall = //Url3;
}
response = doCall(urlToCall);
console.log(response) //Prints undefined
function doCall(urlToCall) {
return co(function *(){
var response = yield urllib.request(urlToCall, { wd: 'nodejs' }); // This is co-request.
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
但如果我在doCall()
中打印值,它将完美打印,但它将始终返回未定义的值。根据我的研究,我知道我们不能从回调函数返回值!(这是真的吗)?如果是,有谁能告诉我如何处理这种情况,因为我想防止在每个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);
});
}
现在:
@罗德里戈在评论中发表了一篇文章。了解节点中的回调及其工作方式。记住,这是异步代码
我在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,那么您可以使用和来实现相同的目标,而无需考虑回调问题
基本上,您可以这样做:
function doCall(urlToCall) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
if(//somecondition) {
urlToCall = //Url1;
} else if(//someother condition) {
urlToCall = //Url2;
} else {
urlToCall = //Url3;
}
response = doCall(urlToCall);
console.log(response) //Prints undefined
function doCall(urlToCall) {
return co(function *(){
var response = yield urllib.request(urlToCall, { wd: 'nodejs' }); // This is co-request.
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
那么
通过这样做,我们等待回调函数完成,然后从中获取值。不知何故,它解决了您的问题。node.js的示例代码-异步函数到同步函数:
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);
}
“这是真的吗?”-是的,当然。@JanDvorak,所以除了复制代码之外,我别无选择?;)传递一些您自己的回调会有帮助吗?我相信是的。我想这个链接会帮助你理解它是如何工作的:@RodrigoMedeiros感谢你提供的优秀资源。我正在经历它,它帮助了我很多:)但这是ecma6解决方案,它也会影响我的性能ecma6是一个问题吗?不,这不是问题,但问题是我们中的许多人仍然没有在他们的项目中使用ecma6,因为node.js在ECMA兼容性方面有一些问题。这很好。但我有一个问题。在调用内部的doCall函数时。如何返回响应变量?例如,如果我想在函数外获取该变量?@Romeo这里有同样的问题!!这篇文章很有帮助,谢谢!嗨,对不起,如果我误解了,但这有什么不同吗?urllib响应现在只是停留在它之外的另一个函数的范围内。这不像你现在可以在doCall之外的任何地方使用响应对象?非常有用。总是避免创建回调,但我现在明白了。谢谢这很有魅力,非常感谢。您可以在这里查看文档