#javascript #jquery #ajax #scope
#javascript #jquery #ajax #область видимости
Вопрос:
У меня есть несколько файлов JavaScript. У меня есть функция JS, которая запускается при загрузке и содержит несколько вызовов AJAX. Каждый вызов AJAX выполняет обратный вызов (а также увеличивает синхронный счетчик):: myArray.push('somevalue');
чтобы я мог проверить, когда завершатся все вызовы AJAX (для этого JS-файла).
Есть ли способ, которым я могу избежать объявления myArray в качестве глобальной переменной, позволяя асинхронным обратным вызовам вставляться в этот массив?
Комментарии:
1. Вам придется переходить
myArray
к каждому вызову.2. Если вы передаете myArray для каждого вызова, он все равно будет ссылаться на эту переменную? Поскольку JS выполняет передачу по значению, асинхронный вызов не будет искать исходную переменную [reference of]?
3. Просто создайте область, которая не является глобальной, jQuery document.ready или IIFE сделают это, и установите массив в той же или более высокой области, чем вызовы ajax.
4. Если вы передаете массив, то значение является ссылкой на массив .
5. у вас есть 2 хороших решения в комментариях здесь, но мой вопрос: почему вы беспокоитесь о том, чтобы сделать этот массив глобальным?
Ответ №1:
Если вы хотите выполнить некоторый код после выполнения заданного количества запросов AJAX, используйте $.when
.
Если вы используете myArray
исключительно для того, чтобы узнать, когда запросы завершены, вы можете удалить его. Если вы используете ее для хранения результата каждого запроса, вы можете сохранить ее в той же области, что и запросы, а затем получить к ней доступ в done
обработчике. Попробуйте это:
var myArray = [];
var ajax1 = $.ajax({
url: '/foo/',
success: function(data) {
myArray.push(data);
});
});
var ajax2 = $.ajax({
url: '/bar/',
success: function(data) {
myArray.push(data);
});
});
$.when(ajax1, ajax2).done(function() {
// both requests complete
// myArray will contain the data of both requests at this point...
for (var i = 0; i < myArray.length; i ) {
console.log(myArray[i]);
}
});
Комментарии:
1. Я не был сторонником отказа, но я думаю, это потому, что вы не рассмотрели ситуацию, о которой спрашивал ОП, может ли он иметь массив, не являющийся глобальным, и назначать ему каждый обратный вызов.
2. Это действительно решает эту проблему — если единственная цель массива — узнать, когда завершатся запросы, тогда массив больше не требуется. Если она используется для хранения результата каждого запроса, она может находиться в той же области, что и сами запросы (т.е. не глобальный), а затем доступ к нему в
done
обработчике.3. Я бы объяснил это и проголосовал за лучшее решение, о котором я только что узнал .when() пару месяцев назад и очистил с его помощью так много кода
4. @ScottSelby да, это действительно удобный метод для управления на тяжелом сайте AJAX. Спасибо за предложения.
5. К сожалению, моя версия jQuery немного отстает, но в настоящее время я рассматриваю возможность обновления.
Ответ №2:
Объявите переменную, доступную только в той области, в которой вы ее хотите (например, внутри функции).
Что-то вроде:
var ajaxCalls = function() {
var myArray = [];
var ajax1 = $.ajax({
url: 'foo.com',
success: function(data) {
myArray.push(data);
});
});
// do more AJAX stuff
$.when(ajax1, ..., ).done(function() {
// make sure all requests are complete
// do stuff with the completed array
});
};
Поскольку JavaScript имеет функциональную область видимости, ваша переменная myArray не будет глобальной, но она будет доступна в рамках обратных вызовов ajax. Надеюсь, это поможет!