web-dev-qa-db-ja.com

Node.jsを完了する要求を待ちます

現在、データが返される前にリクエストが完了するのを待つ方法を理解することに問題があります。コールバックでこれを行うことができるとは信じていません。また、EventEmitterを使用してこれを行う良い方法を理解できていません。コールバックを使用できない理由は、私のフローが現在このように機能しているためです。

リクエストがサーバーに到着> XMLを生成> XMLの生成を終了する詳細についてはリモートAPIに問い合わせ> XMLの生成を終了>クライアントにリクエストを返す

私が現在持っているコードは、以下に含まれているコードと非常によく似ています。

Webサーバー:

var xml = require('./XMLGenerator');
response.writeHead(200, {'Content-Type': 'text/xml'});
response.write(xml.generateXML());
response.end();

XMLジェネレーター:

function generateXML(){
// Code to generate XML
var API = require('./API');
var response = API.getItems("5");
for(var i = 1; i <= response.length; i++)
{
  // more code to generate further XML using the API response
}

// Finish generating and return the XML
}

APIグラバー:

function getItems(sort_by, amount) {
var request = require("request")

var url = "https://url.com/api/get_items.json?amount=" + amount;
request({
    url: url,
    json: true
}, function (error, response, body) {
    console.log('we got here!');
   if (!error && response.statusCode === 200) {
        var items = body.data.items;
        console.log(items);

        return items;
    } else {
        console.log("Error connecting to the API: " + url);
        return;
    }
})
}

コードを実行して直接テストすると、「未定義」が返されます。これは、リクエストがまだ行われていないことを意味します。生成を続行する前に、XMLジェネレーターがリクエストの完了を待機する方法を知る必要があります。 (ソースからの正確なコピー貼り付けではないため、入力したpsudeoコードに小さなエラーがある可能性がありますが、このフローでは機能します)

私は単に悪い習慣を使用しているのですか、それとも私がこれを試みるべき正しい方法ですか?

編集:問題はモジュール/ APIファイルの読み込みではなく、完全に正常に読み込まれます。問題は、リクエストが完了するまでに約2秒かかり、リクエストが完了する前にノードが移動することです。

7
OstlerDev

コールバックを使用する必要があります。 APIグラバーを次のように変更します。

function getItems(amount, callback) {
// some code... 
request({
  url: url,
  json: true
}, function (error, response, body) {
   // some code...
   if (!error && response.statusCode === 200) {
      // some code    
      callback(items); <-- pass items to the callback to "return" it
   }
})
}

次に、xmlジェネレーターを変更して、コールバックも受け入れるようにします。

function generateXML(callback){
// Code to generate XML
var API = require('./API');
API.getItems("5",function(response){
  for(var i = 1; i <= response.length; i++)
  {
    // more code to generate further XML using the API response
  }

  // Finish generating and return the XML
  callback(xml_result); // <-- again, "return" the result via callback
});
}

次に、サーバーコードで次のようにします。

var xml = require('./XMLGenerator');
response.writeHead(200, {'Content-Type': 'text/xml'});
xml.generateXML(function(xmlstring){
    response.write(xmlstring);
    response.end();
});
8
slebetman

requestは非同期なので、これらの変更を行います。コールバックを使用します。

_API.getItems("5", function(rs){
      var response = rs;
      for(var i = 1; i <= response.length; i++)
      {
      // more code to generate further XML using the API response
      }

      // Finish generating and return the XML
    }

});


...
function getItems(sort_by, amount, callback) {...

...
callback(items); //Instead of return items;

...
_

return呼び出しからasyncすることはできません。これは、requestモジュールの場合です。このような場合、約束またはcallbacks。これはコールバックを使用したソリューションです。

undefinedを返す実際の問題は、var response = API.getItems("5");が完全に実行されるのを待たずに次の行を実行するため、responseundefinedとして取得することです。要点を理解していただければ幸いです。\

またね

_response.writeHead(200, {'Content-Type': 'text/xml'});
response.write(xml.generateXML());
response.end();
_

aPIまたは_http.createServer_のコールバック内のどこかにあります。

3
Zee