从Node.js中的回调函数返回一个值

时间:2014-04-28 11:29:19

标签: javascript node.js

我在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块中的重复代码。

4 个答案:

答案 0 :(得分:107)

undefined因为,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,在评论中发布了good resource。阅读节点中的回调以及它们的工作原理。请记住,它是异步代码。

答案 1 :(得分:13)

  

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

callback(finalData);调用需要从异步函数获得的值的函数。但请注意,return语句用于指示函数在此处结束,但它并不意味着该值将返回给调用者(调用者已经移动了。)

答案 2 :(得分:2)

如果你想要的是让代码工作而不需要修改太多。你可以试试这个摆脱回调的解决方案,保持相同的代码工作流程

鉴于您使用的是Node.js,您可以使用coco-request来实现相同的目标,而不会出现回调问题。

基本上,你可以这样做:

var response = yield doCall(urlToCall); // "yield" garuantees the callback finished.
console.log(response) // The response will not be undefined anymore.

然后,

{{1}}

通过这样做,我们等到回调函数完成,然后从中获取值。不知何故,它解决了你的问题。

答案 3 :(得分:1)

node.js的示例代码 - 同步函数的异步函数:

configure