Node.JS等待发出HTTP请求的REST Service的callback

我使用express模块​​在Node.JS中创build一个Restful API。 在我的服务中,我正在向外部端点(服务器端)发出额外的http请求,并且需要将这些http请求中的数据返回给我的Web服务请求主体。

我已经确认,如果我在Web服务正在执行的所有操作上使用console.log ,我正在获取所需的数据。 但是,当我尝试将这些值返回给服务时,他们将返回空值。 我知道这是因为asynchronous和callback不等待http请求完成。

有没有办法做到这一点?

通常的做法是使用asynchronous模块。

 npm install async 

async模块具有原语来处理各种forms的asynchronous事件。

在你的情况下, async#parallel调用将允许你同时向所有的外部API发出请求,然后把结果合并到你的请求者。

由于您正在进行外部http请求,因此您可能会发现请求模块也很有帮助。

 npm install request 

使用requestasync#parallel您的路由处理程序将看起来像这样…

 var request = require('request'); var async = require('async'); exports.handler = function(req, res) { async.parallel([ /* * First external endpoint */ function(callback) { var url = "http://external1.com/api/some_endpoint"; request(url, function(err, response, body) { // JSON body if(err) { console.log(err); callback(true); return; } obj = JSON.parse(body); callback(false, obj); }); }, /* * Second external endpoint */ function(callback) { var url = "http://external2.com/api/some_endpoint"; request(url, function(err, response, body) { // JSON body if(err) { console.log(err); callback(true); return; } obj = JSON.parse(body); callback(false, obj); }); }, ], /* * Collate results */ function(err, results) { if(err) { console.log(err); res.send(500,"Server Error"); return; } res.send({api1:results[0], api2:results[1]}); } ); }; 

您也可以在这里阅读其他callbacksorting方法。

Node.js是关于callback的。 除非API调用是同步的(很less发生并且不应该这样做),否则永远不会从这些调用返回值,而是使用callback方法中的结果进行callback,或者调用快速方法res.send

调用Web请求的好库是request.js

我们来看一个调用google的简单例子。 使用res.send,您的express.js代码可能如下所示:

 var request = require('request'); app.get('/callGoogle', function(req, res){ request('http://www.google.com', function (error, response, body) { if (!error && response.statusCode == 200) { // from within the callback, write data to response, essentially returning it. res.send(body); } }) }); 

或者,您可以将callback传递给调用Web请求的方法,并从该方法中调用该callback:

 app.get('/callGoogle', function(req, res){ invokeAndProcessGoogleResponse(function(err, result){ if(err){ res.send(500, { error: 'something blew up' }); } else { res.send(result); } }); }); var invokeAndProcessGoogleResponse = function(callback){ request('http://www.google.com', function (error, response, body) { if (!error && response.statusCode == 200) { status = "succeeded"; callback(null, {status : status}); } else { callback(error); } }) } 

等等。https ://github.com/luciotato/waitfor

其他答案的例子使用wait.for:

来自Daniel's Answer(asynchronous)的示例,但是使用Wait.for

 var request = require('request'); var wait = require('wait.for'); exports.handler = function(req, res) { try { //execute parallel, 2 endpoints, wait for results var result = wait.parallel.map(["http://external1.com/api/some_endpoint" ,"http://external2.com/api/some_endpoint"] , request.standardGetJSON); //return result res.send(result); } catch(err){ console.log(err); res.end(500,"Server Error") } }; //wait.for requires standard callbacks(err,data) //standardized request.get: request.standardGetJSON = function ( options, callback) { request.get(options, function (error, response, body) { //standardized callback var data; if (!error) data={ response: response, obj:JSON.parse(body)}; callback(error,data); }); }