在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); }