在循环中执行异步XMLHttpRequests,并在所有请求完成后继续
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在循环中执行异步XMLHttpRequests,并在所有请求完成后继续相关的知识,希望对你有一定的参考价值。
我正在尝试在for loop
中执行异步XMLHttpRequests,它会加载一堆JSON。
为了确保在调用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"]);
}
答案
你应该在这里使用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();
oReq.addEventListener("load", function(xhr){ resolve(xhr);});
oReq.addEventListener("error", function(b){reject(this);});
oReq.open('GET', ['https://api.coinmarketcap.com/v1/ticker/' + arrCurrency[i] + '/?convert=EUR'].join(""), true);
oReq.send();
});
all.push(p);
} // loop end
Promise.all(all).then(values => {
values.forEach(function(p){parseJSON(p.currentTarget.responseText);});
nextFunction();
});
以上是关于在循环中执行异步XMLHttpRequests,并在所有请求完成后继续的主要内容,如果未能解决你的问题,请参考以下文章