Chrome扩展程序 - 来自阵列的XHR URL

时间:2010-12-14 23:03:46

标签: javascript google-chrome-extension lifecycle xmlhttprequest

我已经将一些主题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 :(得分:0)

尚未测试,但应该是这样的:

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

}

由于可以按随机顺序调用回调函数,因此您当前的百分比计算将会遍布整个地方。您可能需要重新考虑该部分(创建一些全局计数器)。

答案 1 :(得分:0)

是的,我同意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
            }
        }

    }
}