如何使用 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();
我制作了 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();