2016-04-02 12 views
1

我的目標是爲列表中的各種藝術家記錄所有這些API。 API的含義是每個藝術家都有自己的特點,所以必須多次調用,每個藝術家一次。在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中的相應藝術家的正確位置,但我只記錄了一個JSON。

如果有人能告訴我如何得到它,這樣每個JSON都會記錄下來,每個API都會很棒。我有一種感覺,這是因爲request.responseText需要一段時間,所以它會在完成之前跳過它,導致它只記錄列表中的最後一項。不知道如何解決這個問題。我也不能使用jQuery,因爲我被明確要求不要這個任務。

+0

什麼是你的代碼中的'urling'?你的意思是'urlApi'? –

+0

這是一個API,而不是每個藝術家。 – LinuxDisciple

回答

0

問題很簡單:request是非阻塞的,因此當調用request.send()時,它允許for循環完成。但是當for循環開始下一次迭代時,request被覆蓋,所以只有最後的請求被記錄。

有兩種方法來解決這個問題:

  • 變化truefalserequest。這將它從非阻塞變爲阻塞,並會暫停循環,直到請求結束並獲得響應。那麼你保證它會工作。

  • 使用map收集您的結果。即呼叫artistList.map(makeRequest),其中makeRequest使用來自artistList的藝術家作爲輸入返回XMLHTTP請求的結果。

    (我不保證這會工作!到處尋找工作的東西相當於一個異步請求超過數組,如果沒有,或者使用第一種方法。)

0

你應該在for循環之前聲明一個對象。並在其中添加所有記錄。

實施例:

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

結果[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應用於所有函數。

爲了克服這個問題,我們必須通過傳遞循環的當前請求對象作爲參數來執行每個循環中的函數,現在在這個函數範圍內,請求變量總是作爲參數傳遞的。