2016-04-02 10 views
1

私の目標は、リストにあるさまざまなアーティストのためにこれらのAPIをすべてログに記録することです。 APIを使っていることは、各アーティストが独自のアーティストを持っているため、アーティストごとに1回、複数回呼び出す必要があることです。Javascriptのforループで別のAPIを実行する

var artistList = [...]; //let's say there is a hypothetical 100 artists 
var n = artistList.length; //this would be 100 

for (var i=0; i<n; i++) { 
    var request = new XMLHttpRequest(); 
    var urlApi = 'http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=' + artistList[i] + '&api_key=somApiKeyThatWorks&format=json'; 
    console.log(urlApi); 
    request.open('GET', urling, true); 

    request.onload = function() { 
     if (request.status >= 200 && request.status < 400) { 

     var data = JSON.parse(request.responseText); 
     console.log(data); 
     } else { 

     } 
    }; 

    request.onerror = function() { 
    }; 

    request.send(); 
}; 

これを実行してコンソールを確認すると、直前にリストされた項目のみがデータとして表示されます。だから私は、これらのすべてのAPIを記録し、各APIの対応するアーティストと正しく取得しますが、私は1つのJSONをログに記録します。

誰でも私にそれを入手する方法を教えてもらえれば、それぞれのJSONが偉大になるAPIごとに記録されるようになります。 request.responseTextのために時間がかかるので、これが終了する前にスキップして、リストの最後の項目だけを記録するという結果になったと感じています。これにアプローチする方法を知らない。 jQueryを使用することはできません。なぜなら、この割り当てをしないように明示的に求められていたからです。

+0

あなたのコードに 'urling'とは何ですか?あなたは 'urlApi'を意味しましたか? –

+0

これは1つのAPIであり、アーティストごとに1つではありません。 – LinuxDisciple

答えて

0

問題は単純です:requestは非ブロッキングなので、request.send()が呼び出されるとforループが終了します。しかし、forループが次の反復を開始すると、requestが上書きされるので、の最後の要求だけがログに記録されます。 requestfalse

  • 変更true

    は、これを解決するには、2つの方法があります。非ブロッキングからブロッキングに変更され、リクエストが終了して応答が得られるまでループが一時停止します。その後、それは動作することが保証されます。

  • mapを使用して結果を収集します。すなわちartistList.map(makeRequest)を呼び出します。makeRequestは、artistListのアーティストを入力としてXMLHTTPRequestの結果を返します。

    (私はこれが動作する保証するものではありません!それがない場合のアレイ上で動作する非同期リクエストと同等の何かのために周りを見て、または最初のメソッドを使用します。)

0

forループの前に1つのオブジェクトを宣言する必要があります。その中にすべてのレコードを追加します。

例:

 var artistList = [...]; //let's say there is a hypothetical 100 artists 
     var n = artistList.length; //this would be 100 

VAR結果= {};

 for (var i=0; i<n; i++) { 
      var request = new XMLHttpRequest(); 
      var urlApi = 'http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=' + artistList[i] + '&api_key=somApiKeyThatWorks&format=json'; 
      console.log(urlApi); 
      request.open('GET', urling, true); 

      request.onload = function() { 
       if (request.status >= 200 && request.status < 400) { 

       var data = JSON.parse(request.responseText); 
       console.log(data); 

結果[artistList [I] =データ。今

   } else { 

       } 
      }; 

     request.onerror = function() { 
     }; 

     request.send(); 
    }; 

、あなたはresultsオブジェクト内のすべてのデータを持っています。

うまくいけば、うまくいくでしょう。

0

これはInfamous Loop Problemです(内容をスクロールしてThe Infamous Loop Problem is discussed)これは、関数を持つループを扱うときに知っておく必要があります。これを動作させるには、この構文を使用します。ここでの問題点を説明する

request.onload = function(thisRequest) { // this is the current request and now inside this block it will refer to the same request object. 
    return function(){ 
    if (thisRequest.status >= 200 && thisRequest.status < 400) { 
    var data = JSON.parse(thisRequest.responseText); 
    console.log(data); 
    } 
    else { 
    } 
    } 

}(request); //pass the current request as the parameter to this function and execute 

リクエスト変数の各ループの変更、そしてonload関数を実行だけに適用されていないため、リクエスト変数は、ループの終わりまで変更し続けます。したがって、forループが終了すると、最後の値requestがすべての関数に適用されます。

この問題を解決するには、ループの現在のリクエストオブジェクトをパラメータとして渡すことによって各ループで関数を実行する必要があります。この関数スコープ内では、要求変数は常にパラメータとして渡されます。

関連する問題