JQuery AJAX вызывает цикл for
Я новичок в использовании AJAX, и я пишу usercript, который обрабатывает кучу ссылок на странице и делает вызовы AJAX для каждого из них.
for (var i = 0; i < linkList.length; i++)
{
$.ajax({
url: linkList[i].getAttribute("href"),
cache: false
}).done(function( html )
{
var hasAppended = false;
if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended)
{
hasAppended = true;
var id = linkList[i].getAttribute("href").substring(linkList[i].getAttribute("href").indexOf('='));
$( "#links a[href*='" + id + "']" ).append(' THIS PAGE CONTAINS SPECIFIED DATA');
}
});
}
Чтобы попросту сказать, у меня есть страница со списком ссылок. Я хочу перебирать ссылки и получать AJAX для обработки содержимого каждой из страниц ссылок и отчитываться, если эта страница содержит что-то определенное.
Проблема, с которой я столкнулась, - это значение [i], используемое для итерации через linkList, всегда 6, и этого никогда не должно быть. Я предполагаю, что мне нужно передать некоторые данные, чтобы, когда .done, наконец, запускает, он знает свое значение [i] с момента запуска AJAX, а не значения [i], когда .done запускает позже.
Как мне обеспечить, что .done знает это значение [i], когда AJAX сначала вызывается?
Ответы
Ответ 1
Самый простой способ - использовать закрытие. Всякий раз, когда у вас есть что-то асинхронное в цикле, это одно и то же.
for (var i .....) {
async(function() {
use(i);
}
}
В этом фрагменте псевдокода внутренняя функция фиксирует местоположение хранилища, на которое ссылается i
. Цикл выполняется, значение i
увеличивается до конечного значения, а затем вызываются вызовы async, все они ищут то же самое местоположение (не значение).
Общее решение таково:
for (var i .....) {
(function (i) {
async(function() {
use(i);
});
})(i);
}
то есть. оберните все содержимое вашего цикла в функцию самоисполнения.
Здесь значение внешнего i
передается в анонимную функцию обертывания; это уникальное местоположение значения захватывается асинхронным обратным вызовом. Таким образом, каждый async получает свое собственное значение, определенное в момент вызова функции самоисполнения.
Ответ 2
Ссылки в разделе комментариев вопроса говорят вам, что не так в вашем коде... но вы можете иметь лучшее решение, чем когда-то объясняемое там.
Попробуйте $. each() выполнить итерацию по списку (при условии, что это массив), так что пройденный обратный вызов создаст отдельное закрытие для каждой итерации
$.each(linkList, function (i, item) {
$.ajax({
url: item.getAttribute("href"),
cache: false
}).done(function (html) {
var hasAppended = false;
if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) {
hasAppended = true;
var id = item.getAttribute("href").substring(item.getAttribute("href").indexOf('='));
$("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA');
}
});
})
Если это объект jQuery, используйте .each()
linkList.each(function (i, item) {
var $item = $(item),
href = $item.attr("href");
$.ajax({
url: href,
cache: false
}).done(function (html) {
var hasAppended = false;
if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) {
hasAppended = true;
var id = href.substring(href.indexOf('='));
$("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA');
}
});
})