42

Express モジュールを使用して、Node.js 内で RESTful API を構築しています。私のサービスでは、外部エンドポイント (サーバー側) に追加の HTTP リクエストを作成しています。これらの HTTP 要求からのデータを Web サービスの要求本文に返す必要があります。

Web サービスが実行しているすべてのアクションで、console.log()必要なデータを取得できることを使用して確認しました。ただし、これらの値をサービスに返そうとすると、 value が返されますnull。これは、リクエストが非同期で、コールバックが HTTP リクエストの完了を待っていないためです。

これを機能させる方法はありますか?

4

3 に答える 3

43

一般的な方法は、asyncモジュールを使用することです。

npm install async

asyncモジュールには、さまざまな形式の非同期イベントを処理するためのプリミティブがあります。

あなたの場合、async#parallel呼び出しにより、すべての外部 API に同時にリクエストを作成し、結果を組み合わせてリクエスターに返すことができます。

外部の http リクエストを作成しているので、おそらくrequestモジュールも役立つでしょう。

npm install request

requestとルートハンドラを使用するとasync#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]});
  }
  );
};

他のコールバック シーケンス メソッドについては、こちらを参照してください。

于 2013-05-31T21:13:03.480 に答える
3

Wait.for 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);
            });
}
于 2013-09-06T14:24:13.377 に答える