簡體   English   中英

Node.JS等待發出HTTP請求的REST服務的回調

[英]Node.JS Wait for callback of REST Service that makes HTTP request

我正在使用express模塊​​在Node.JS中創建Restful API。 在我的服務中,我正在向外部端點(服務器端)發出額外的http請求,我需要將這些http請求中的數據返回給我的Web服務請求體。

我已經確認,如果我在Web服務正在執行的所有操作上使用console.log ,我將獲得所需的數據。 但是,當我嘗試將這些值返回給服務時,它們會返回Null。 我知道這是因為異步並且回調不等待http請求完成。

有沒有辦法讓這項工作?

通常的做法是使用異步模塊。

npm install async

async模塊具有處理各種形式的異步事件的原語。

在您的情況下, 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]});
  }
  );
};

您還可以在此處閱讀其他回調排序方法。

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

或者,您可以將回調傳遞給調用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);
    }
  })
}

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

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

來自Daniel's Answer(async)的示例,但使用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);
            });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM