Расширение Chrome - XHR URL из массива - PullRequest
0 голосов
/ 15 декабря 2010

Я сохранил некоторые предметные URL-ключи в localStorage и теперь хочу перебирать их, чтобы получить содержимое каждого из них.

// 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.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();
    }
}

Это не работает, он перехватывает только первый URL, после чего в моем журнале консоли сообщается, что все остальные URL были установлены, но закрытие xhrIn [i] .onreadystatechange никогда не выполнялось.

Это выглядит немного волшебно для меня ... Кто-нибудь может объяснить мне такое поведение?

Ответы [ 2 ]

0 голосов
/ 15 декабря 2010

Да, я согласен с epascarello, с этим кодом есть некоторые фундаментальные проблемы. Не гарантируется, что обратные вызовы, назначенные для запуска в том порядке, в котором вы собираетесь. Если вы хотите, чтобы они работали по порядку, попробуйте что-то вроде этого:

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
            }
        }

    }
}
0 голосов
/ 15 декабря 2010

Не проверял, но должно быть что-то вроде этого:

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

}

Ваш текущий расчет процентов будет перескакивать повсюду, так как функции обратного вызова могут вызываться в случайном порядке.Возможно, вам придется переосмыслить эту часть (создать некоторый глобальный счетчик).

...