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