在Node.js中从callback函数返回一个值
我在Node.js中从callback函数返回一个值时遇到了一些麻烦,我会尽可能简单地解释我的情况。 考虑我有一个代码片段,它需要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 。 根据我的研究,我开始知道我们不能从callback函数返回值!  (是真的)? 如果是的话,任何人都可以告诉我如何处理这种情况,因为我想防止在每个if-else块中重复的代码。 
 其undefined因为, console.log(response)之前运行doCall(urlToCall); 完成。 你必须传递一个callback函数,当你的请求完成时运行。 
首先,你的function。 通过callback:
 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,在评论中张贴了一个很好的资源 。 阅读节点中的callback以及它们是如何工作的。 请记住,这是asynchronous代码。
我在Node.js中从callback函数返回值时遇到了一些麻烦
这不是一个“小麻烦”,实际上不可能从asynchronous函数中“返回”传统意义上的值。
既然你不能“返回值”,你必须调用一旦你有它的值将需要的函数。 @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; }); } 
 线callback(finalData); 是什么调用需要你从asynchronous函数获得的值的函数。 但是请注意,return语句用于指示函数在这里结束 ,但并不意味着该值返回给调用者 (调用者已经移动了)。 
如果你想要的是让你的代码工作,而不是修改太多。 你可以试试这个解决scheme,它可以消除callback并保持相同的代码工作stream程 :
鉴于您正在使用Node.js,您可以使用co和co-request来实现相同的目标,而不用担心callback。
基本上,你可以做这样的事情:
 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; }); } 
然后,
 var response = yield doCall(urlToCall); // "yield" garuantees the callback finished. console.log(response) // The response will not be undefined anymore. 
通过这样做,我们等待callback函数完成,然后从中获取值。 不知何故,它解决了你的问题。
node.js的示例代码 – asynchronous函数同步function:
 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); }