У нас есть асинхронный поиск, в поле ввода по буквам вводится текст и автоматически обновляются результаты поиска. На первый взгляд — ничего сложного, повесим на input событие keyup, при срабатывании которого будет происходить новый поиск по новой фразе.
document.getElementById('search').addEventListener('keyup', function() { // Мы не будем описывать тело функции search, она реализует то, что было описано выше search(); });
Но за то время, пока выполняется запрос, пользователь может успеть набрать следующую букву, тогда результаты предыдущего запроса будут уже неактуальны, а новый запрос не выполнится пока не закончится предыдущий (тут я слукавил, XHR запрос можно и отменить, но это частный случай). Представьте, что пользователь вводит быстро словосочетание «Дешевые билеты в Камбоджу». В таком случае функция search вызовется 25 раз. Это излишне. С другой стороны, если пользователь вводит не так быстро, то хорошо бы показывать ему промежуточные варианты, и еще нежелательно иметь какие-то задержки перед показом результатов.
Для этого и была изначально придумана «Ожидающая функция». Она ждет, пока прекратится ее цикличный вызов, т.е. если пройдет заданное время после ее вызова, и эта функция не будет вызвана повторно, то она выполняется, иначе действие передается следующему вызову.
fnDelay = (function(){ var timer = 0; return function(callback, ms){ clearTimeout(timer); timer = setTimeout(callback, ms); }; })();
И сразу же покажу как ее использовать.
document.getElementById('search').addEventListener('keyup', function() { fnDelay(function() { search(); }, 200); });
Эффективность выполнения этой функции регулируется аргументом ms. Для каждого конкретного случая нужно искать свою золотую середину, чтобы результат был и отзывчивым и не накапливалась очередь невыполненных задач. Теперь если пользователь при вводе сделает паузу хотя бы в 200 мс, то он получит новые результаты. Тем самым мы значительно уменьшаем количество вызовов функции search.
Я не остановился на асинхронном поиске, используя эту же функцию, когда мне нужно что-то сделать при ресайзе страницы, так как изменяя ширину окна всего лишь на 100 пикселей, событие resize может быть вызвано десятки раз.
Добавлю также ссылку на небольшой Фидл с примером.
ссылка на оригинал статьи http://habrahabr.ru/post/228325/
Добавить комментарий