Асинхронная обработка событий поиска - PullRequest
2 голосов
/ 09 июня 2011

У меня есть поисковый ввод через Интернет.При каждом событии onkeyup выполняется асинхронный запрос от клиента с JavaScript к документу PHP, который возвращает ответ на запрос поиска, а затем JS принимает ответ на запрос поиска и записывает его клиенту.Эта часть работает нормально.

Однако моя проблема заключается в том, что пользователь вводит свой поисковый запрос быстрее, чем система может ответить.

Допустим, пользователь, который быстро печатает, выполняет поискслово super.Пользователь вводит s (и поиск выполняется для s), в то время как поиск выполняется и записывается для s, пользователь вводит u, и теперь поиск для su ставится в очередь.Затем этот очень быстрый пользователь печатает p, в то время как начальный поиск s завершается, и теперь поиски su и sup ставятся в очередь.

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

Как я могу улучшить свой код, чтобыулучшить пользовательский опыт?

Например, как бы вы написали этот сценарий так, чтобы любые элементы в очереди, кроме последнего, были удалены?

Ответы [ 3 ]

4 голосов
/ 09 июня 2011

Вы можете сделать это за один тайм-аут (называемый debouncing ):

"Debouncing означает объединение нескольких временно закрытых сигналов водин сигнал. "

var timer;
function keyup() {
  clearTimeout(timer);
  timer = setTimeout(function() {
    search(this.value);
    timer = null;
  }, timer ? 50 : 1);
}

Этот код означает, что если пользователь печатает слишком быстро (дельта <50 мс в этом случае), действие не будет поставлено в очередь, но самое новое всегдаперезаписывает предыдущие. </p>

Существует другой подход (называемый регулирование ):

"Регулирование - это уменьшениечастота повторяющегося события. "

var timer;
function keyup() {
  if (!timer)
    timer = setTimeout(function() {
      search(this.value);
      timer = null;
    }, 100);
  }
}

Наконец, вы можете получать больше данных за раз, чтобы обойти проблемы с задержкой.
См. этот пост, чтобы узнать, как Flickr делает это: Построение быстрых запросов на стороне клиента

Также убедитесь, что вы используете какой-то вид кэширования (APC / memcache) в зависимости от того, как часто ваши данныеизменения.Это может значительно снизить нагрузку на вашу базу данных.

3 голосов
/ 09 июня 2011

Я думаю, что лучшее решение - это таймер для "onkeyup".

Образец с JQuery:

var timer = null;
$('input').keyup(function(){
    if(timer!=null){
        clearTimeout(timer);
    }
    // wait and call in 150 ms
    timer = setTimeout(function() {
        // call here your search function!
        ....
    }, 150);
});
0 голосов
/ 09 июня 2011

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

Если данные являются кандидатами на выборку и сохранение при загрузке страницы, вы можете предоставить гораздо более быстрое решение для автозаполнения, просто извлекая его из памяти на стороне клиента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...