如何使用 ajax 进行循环而不冻结我的 Firefox 扩展?

How to make for loop with ajax not freeze my Firefox Extension?

我制作了 firefox 扩展程序,它每分钟 ajax 调用一次。

脚本的作用是查看给定页面上的 LI 元素,然后 returns page/position 如果找到匹配项

这是我有问题的代码的一部分:

var item_name = 'test';
var items_per_row = 8;
var last_index;
var last_status;
var x = new XMLHttpRequest();
x.open('GET', 'http://example.com/script.php?page=0', false);
x.onload = function(e) {
    var doc = document.implementation.createHTMLDocument("document"); doc.documentElement.innerHTML = x.responseText;
    var bool = $("div.l1 p",doc).filter(function() { return $(this).text() == item_name});
    last_index = $("div.l1 p",doc).index(bool)+1;
    if(bool.length){ // if match found on first page
        inspector4pda.cScript.position = bool.length+""+Math.ceil(last_index/items_per_row)+""+("0" + last_index).slice (-2);
    } // Main page
    else // Other pages
    {
        var found = false;
        jQuery.ajaxSetup({async:false});
        for(var i=1;i<15;i++)
        {
            $.get( "http://example.com/script.php?page="+i, function( data ) { 
                    var doc2 = document.implementation.createHTMLDocument("document2");
                    doc2.documentElement.innerHTML = data;
                    var bool = $("div.l1 p",doc2).filter(function(index) { return $(this).text() == item_name});
                    last_index = $("div.l1 p",doc2).index(bool)+1;
                    if(bool.length == true){ 
                        found=true;
                        last_status = $("div.l1 p",doc2).eq(last_index-1).parents("li").find(".l2 p").attr("class").split(/\s+/)[0];
                    }
                });
            if(found){ 
                if(last_status == "g-mem"){ inspector4pda.cScript.position = "Плат"; break; }
                if(last_status == "g-dis"){ inspector4pda.cScript.position = "Диск"; break; }
                if(last_status == "g-pri"){ inspector4pda.cScript.position = "Прив"; break; }
                if(last_status == "g-vid"){ inspector4pda.cScript.position = i+1+""+Math.ceil(last_index/items_per_row)+""+("0" + last_index).slice (-2); break; }
            }
        }
        jQuery.ajaxSetup({async:true});
        if(!found) { 
            inspector4pda.cScript.position = "OFF"; 
        }
    }
}
x.send();

with "jQuery.ajaxSetup({async:false}); 它有效,但冻结了几秒钟(因为同步等待所有 $.get 调用)我不想要。如果我删除问题已经解决了,但是脚本不起作用...(我希望 $.get 调用在彼此之后执行)

所以我的问题是有没有办法(回调之类的)告诉我的

 if(found)

等待所有 $.get 调用然后完成它的工作,而不使用 async:false 和冻结浏览器?

谢谢!

您可以简单地放置一个计数器并在每次回调时增加它,然后让满足目标数量的回调调用后续操作。

或者,您可以将每个 ajax 调用转换为 promise 并使用 Promise.all(...ajaxPromises).then(followupAction)

这应该可行,尽管我在这里混合了 let 以便提升 theUrl 如果您在那种情况下使用 var,我认为它会执行相同的 URL。

我在这里所做的是设置一个计数器。

var item_name = 'test';
var items_per_row = 8;
var last_index;
var last_status;
var x = new XMLHttpRequest();
x.open('GET', 'http://example.com/script.php?page=0', false);
x.onload = function(e) {
    var doc = document.implementation.createHTMLDocument("document"); doc.documentElement.innerHTML = x.responseText;
    var bool = $("div.l1 p",doc).filter(function() { return $(this).text() == item_name});
    last_index = $("div.l1 p",doc).index(bool)+1;
    if(bool.length){ // if match found on first page
        inspector4pda.cScript.position = bool.length+""+Math.ceil(last_index/items_per_row)+""+("0" + last_index).slice (-2);
    } // Main page
    else // Other pages
    {
        var found = false;
        jQuery.ajaxSetup({async:true});
    var requestCompletions = {};
        for(var i=1;i<15;i++)
        {
            requestCompletions['http://example.com/script.php?page='+i] = 0;

    }
        for(var i=1;i<15;i++)
        {
        let theUrl = "http://example.com/script.php?page="+i;
            $.get( theUrl, function( data ) {

                    var doc2 = document.implementation.createHTMLDocument("document2");
                    doc2.documentElement.innerHTML = data;
                    var bool = $("div.l1 p",doc2).filter(function(index) { return $(this).text() == item_name});
                    last_index = $("div.l1 p",doc2).index(bool)+1;
                    if(bool.length == true){ 
                        found=true;
                        last_status = $("div.l1 p",doc2).eq(last_index-1).parents("li").find(".l2 p").attr("class").split(/\s+/)[0];
                    }
            // mark this request completed and see if all requests completed:
            delete requestCompletions[theUrl];
            if (Object.keys(requestCompletions).length == 0) {
                // ok all requests done:
                        if(found){ 
                            if(last_status == "g-mem"){ inspector4pda.cScript.position = "Плат"; break; }
                            if(last_status == "g-dis"){ inspector4pda.cScript.position = "Диск"; break; }
                            if(last_status == "g-pri"){ inspector4pda.cScript.position = "Прив"; break; }
                            if(last_status == "g-vid"){ inspector4pda.cScript.position = i+1+""+Math.ceil(last_index/items_per_row)+""+("0" + last_index).slice (-2); break; }
                        }
            } 

                });
        }
        jQuery.ajaxSetup({async:true});
        if(!found) { 
            inspector4pda.cScript.position = "OFF"; 
        }
    }
}
x.send();