Chrome Extension - XHR URLs from an array
I have saved some subject URL keys to localStorage and now want to cycle through them a get content of each of them.
// Walk through saved subjects
allSubjects = JSON.parse(localStorage.getItem('subjects'));
var i = 0;
var ii = 0;
var xhrIn = [];
for (i = 0; i < allSubjects.length; i++) {
xhrIn[i] = new XMLHttpRequest();
xhrIn[i].open("GET", "https://myserver.com/" + allSubjects[i], true);
xhrIn[i].onreadystatechange = function() {
if (xhrIn[ii].readyState == 4) {
console.开发者_JAVA百科log(xhrIn[ii].responseText);
percents = Math.floor((((ii+1)/allSubjects.length)*100));
$("div#status").text('Downloading... ' + percents + '%');
// Final phase
if ((ii+1) == allSubjects.length) {
$("div#status").text("All downloaded and saved in console.");
}
ii++;
}
};
xhrIn[i].send();
}
}
This is not working, it catches only the first URL, after that my Console log says, that all other URLs were contacted, but xhrIn[i].onreadystatechange closure has never been executed.
It looks like a little bit magical for me... Can anyone explain me this behavior?
Yes, I agree with epascarello, there are some fundamental problems with this code. There is not guarantee that the callbacks assigned to run in the order you are intending. If you want them to run in order, try something like this:
var urls = ['test.php', 'test2.php', test3.php'];// and so on
function myRequest(){
if(urls.length > 0){
var nextUrl = urls.pop(); //TAKE THE NEXT URL (pop() removed from the end)
var xhrIn = new XMLHttpRequest();
xhrIn.open("GET", "https://myserver.com/" + nextUrl, true);
xhrIn.onreadystatechange = function() {
if (xhrIn.readyState == 4) {
console.log(xhrIn.responseText);
//THE FOLLOWING LINE WILL OBVIOUSLY NOT WORK ANY MORE
//percents = Math.floor((((ii+1)/urls.length)*100));
//$("div#status").text('Downloading... ' + percents + '%');
myRequest(); //RECUR WHEN DONE WITH PREVIOUS REQUEST
}
}
}
}
Haven't tested, but should be something like this:
for (i = 0; i < allSubjects.length; i++) {
xhrIn[i] = new XMLHttpRequest();
xhrIn[i].open("GET", "https://myserver.com/" + allSubjects[i], true);
xhrIn[i].onreadystatechange = (function(ii) {
return function() {
if (xhrIn[ii].readyState == 4) {
console.log(xhrIn[ii].responseText);
}
};
})(i);
xhrIn[i].send();
}
Your current percent calculation will jump all over the place as callback functions could be called in random order. You probably would need to rethink that part (create some global counter).
精彩评论