Node.JS等待发出HTTP请求的REST服务的回调

Rob*_*Rob 39 javascript api rest http node.js

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

我已经确认,如果我使用console.logWeb服务正在执行的所有操作,我将获得所需的数据.但是,当我尝试将这些值返回给服务时,它们会返回Null.我知道这是因为异步并且回调不等待http请求完成.

有没有办法让这项工作?

Dan*_*iel 42

通常的做法是使用异步模块.

npm install async
Run Code Online (Sandbox Code Playgroud)

async模块具有处理各种形式的异步事件的原语.

在您的情况下,该async#parallel调用将允许您同时向所有外部API发出请求,然后将结果组合以返回给您的请求者.

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

npm install request
Run Code Online (Sandbox Code Playgroud)

使用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]});
  }
  );
};
Run Code Online (Sandbox Code Playgroud)

您还可以在此处阅读其他回调排序方法.


Ove*_*d D 17

Node.js就是回调.除非API调用是同步的(很少见且不应该完成),否则永远不会从这些调用中返回值,而是使用回调方法中的结果回调,或者调用express方法res.send

用于调用Web请求的一个很棒的库是request.js

让我们来看看调用谷歌这个非常简单的例子吧.使用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);
    }
  })
});
Run Code Online (Sandbox Code Playgroud)

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

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);
    }
  })
}
Run Code Online (Sandbox Code Playgroud)