2017-12-26 47 views
0

for loop에서 비동기 XMLHttpRequests를 실행하려고합니다. 많은 JSON이로드됩니다.루프에서 비동기 XMLHttpRequests를 실행하고 모든 요청이 완료되면 계속 진행하십시오.

nextFunction()을 호출하기 전에 모든 XMLHttpRequests 요청이 완료되었는지 확인하려면 xhr.onreadystatechange을 사용하고 있습니다. 이것은 정상적으로 작동하지만 마지막 nextFunction()이 실행 중이며 마지막 XMLHttpRequest가 완료됩니다.

왜 이렇게됩니까? 그리고 내가 뭘 잘못하고있어?

var arrCurrency = ['Bitcoin', 'Ethereum', 'Litecoin', 'Ripple']; 
 
arrJSON = []; 
 
createCurrencyArray(); 
 

 
function createCurrencyArray() { 
 

 
    var count = 0; 
 

 
    for (var i = 0; i < arrCurrency.length; i++) { 
 

 
    var url = 'https://api.coinmarketcap.com/v1/ticker/' + arrCurrency[i] + '/?convert=EUR'; 
 

 
    getJSON(url, parseJSON); 
 

 
    function parseJSON() { 
 
     var a = this.responseText; 
 
     var b = a.slice(1, -1); 
 
     var c = JSON.parse(b); 
 
     arrJSON.push(c); 
 
    } 
 
    } 
 

 
    function xhrSuccess() { 
 
    this.callback.apply(this, this.arguments); 
 
    } 
 

 
    function getJSON(url, callback) { 
 

 
    var xhr = new XMLHttpRequest(); 
 
    xhr.callback = callback; 
 
    xhr.onload = xhrSuccess; 
 
    xhr.onreadystatechange = function() { 
 

 
     if (xhr.readyState == 4) { 
 

 
     count++; 
 
     console.log('state:' + xhr.readyState + ' JSON-' + count + ' loaded') 
 

 
     if (count == arrCurrency.length) { 
 
      console.log("Done: All JSONs loaded"); 
 
      nextFunction(); 
 
     } 
 
     } 
 
    } 
 
    xhr.open("GET", url, true); 
 
    xhr.send(null); 
 
    } 
 
} 
 

 
function nextFunction() { 
 
    console.log(arrJSON); 
 
    console.log('array length: ' + arrJSON.length); 
 
    console.log('array key 0: ' + arrJSON[0]["id"]); 
 
    console.log('array key 1: ' + arrJSON[1]["id"]); 
 
    console.log('array key 2: ' + arrJSON[2]["id"]); 
 
    console.log('array key 3: ' + arrJSON[3]["id"]); 
 
}

+0

Promise.all이 (jQuery를에 $의 q.all() 나는 생각한다) –

+0

내가 생각을 해결할 것이라고 XHR 작업이 성공, onreadystate (여기서 상태 == 4) 화재 및 온로드 화재. 나는 당신이 절반의 코드 절반을 다른 것에 가지고 있는지 확신하지 못한다. 나는 모든 작업을 위해 하나의 xhr 이벤트 핸들러를 사용해야한다고 생각한다. – James

+0

내가 프로가 아니기 때문에 내 코드가 보인다 ... 나는 그것을 정리하고 이벤트 리스너'xhr.addEventListener ("load", function() {if (this.status == 200) {//성공}'. 지금 일하고있는 것 같습니다. – MrtJa

답변

0

현재 promises를 사용해야하고 모든 요청은 처리 결과를 완료 한 경우.

var arrCurrency = ['Bitcoin', 'Ethereum', 'Litecoin', 'Ripple'], arrJSON = [], all = []; 
 

 
function nextFunction() { 
 
    console.log('array length: ' + arrJSON.length); 
 
    arrJSON.forEach((entry,idx)=>{console.log('array-key '+idx+': ' + arrJSON[idx].id); }); 
 
    console.log(arrJSON); 
 
} 
 

 
function parseJSON(jsn) { 
 
    var obj = jsn.slice(1, -1); 
 
    var jsnObj = JSON.parse(obj); 
 
    arrJSON.push(jsnObj); 
 
} 
 
    
 
for(i=0; i < arrCurrency.length; i++){  
 
    
 
    var p = new Promise(function(resolve,reject){ 
 
    var oReq = new XMLHttpRequest(); \t 
 
\t oReq.addEventListener("load", function(xhr){ resolve(xhr);}); 
 
\t oReq.addEventListener("error", function(b){reject(this);}); 
 
\t oReq.open('GET', ['https://api.coinmarketcap.com/v1/ticker/' + arrCurrency[i] + '/?convert=EUR'].join(""), true); 
 
\t \t oReq.send(); 
 
    }); 
 
    all.push(p); 
 
} // loop end 
 
    
 
Promise.all(all).then(values => { 
 
    values.forEach(function(p){parseJSON(p.currentTarget.responseText);}); 
 
    nextFunction(); 
 
});