Главная страница   /   14.2. Избежание наиболее распространенных ловушек Ajax (Pro jQuery

Pro jQuery

Pro jQuery

Адам Фриман

14.2. Избежание наиболее распространенных ловушек Ajax

Прежде чем продолжить, я хочу показать вам наиболее распространенная ошибки, которая делает веб-программист используя Ajax, забывая, что это асинхронный запрос. В листинге 14-14 приведен пример ошибки.

Листинг 14-14: Распространенная Ajax ошибка
<script type="text/javascript">
	$(document).ready(function () {
		$('<button>Ajax</button>').appendTo('#buttonDiv').click(function (e) {
			e.preventDefault();

			var elems;

			$.get("flowers.html", function (data) {
				elems = $(data).filter("div").addClass("dcell");
			});

			elems.slice(0, 3).appendTo('#row1');
			elems.slice(3).appendTo("#row2");
		});
	});
</script>

В этом скрипте я определил переменную с именем elems, которая затем используется функцией обратного вызова Ajax для указания результата серверного запроса. Затем я использую методы slice и appendTo, чтобы добавить элементы, полученные с сервера, в документ. Если вы запустите этот пример, вы увидите, что ни один элемент не добавлен в документ; и в зависимости от того, какой у вас браузер, на консоли вы увидите сообщение об ошибке. Вот сообщение, показанное Google Chrome:

Uncaught TypeError: Cannot call method 'slice' of undefined

Ошибка в данном случае заключается в том, что выражения в элементе script не выполнены в том порядке, в котором они написаны. Проблема заключается в том, что я предположил, что все будет происходить в такой последовательности:

  1. Определение переменной elems
  2. Получение данных с сервера и их присвоение переменной elems
  3. Разделение элементов в переменной elems и добавление их в документ

Что на самом деле произошло:

  1. Определение переменной elems
  2. Начало асинхронного запроса на сервер
  3. Разделение элементов в переменной elems и добавление их в документ

И в какой-то момент в ближайшем будущем, это происходит:

  1. Получение запроса с сервера
  2. Обработка данных и их присвоение переменной elems

Вкратце, вы получили сообщение об ошибке, потому что вы вызвали метод slice для переменной, которая не содержит никаких элементов. Самая плохая вещь в этой ошибке заключается в том, что иногда код действительно работает. Это потому что ответ Ajax завершается так быстро, что переменная получает ожидаемые данные прежде, чем вы начинаете их обрабатывать (обычно это случается, если данные закешированы браузером или вы выполняете некоторые сложные манипуляции между запуском Ajax запроса и попыткой оперировать данными). Теперь вы знаете, где нужно искать, если вдруг ваш код повел себя подобным образом.