Поиск в БД через AJAX, Логика очередности выполнения

97
20 мая 2021, 08:50

Есть поле поиска по базе.

<input id="search">

Есть Ajax скрипт с запросом который после выполнения перерисовывает либо добавляет данные в таблицу в браузере. Данных много, скрипт тоже тяжеленький. Скрипт привязан на событие onChange / onInput поля.

Суть такова. Если в AJAX запросе отключить асинхронность, то все работает как надо. Браузер стопорится, ждет окончание запроса, выводит инфу, оживает и ждет дальнейших действий. (изменение строки поиска).

Но если асинхронность включить, то время поиска по разному кол-ву букв отличается. И В итоге при наборе 3-4х букв скрипт мне видает информацию по 1 или 2-й букве.

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

Если во время выполнения запроса пытаемся нажать еще пару букв, то они выполняться не будут, ибо отменяется запуск запроса, пока старый не отработается.

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

Answer 1

Всё что вам нужно сделать, это не забывать про созданный для поиска объект запроса, и для нового поиска, если запрос уже существует вызывать его прерывание (для jquery тоже можно var rq = $.ajax(...); rq.abort();).

Answer 2

1 вариант - запрещать ввод в поле пока не завершится запрос. Тут либо добавить readonly, либо может быть поверх невидимый блок положить, и не забыть focus снять с поля.

2 вариант - кроме запрета выполнения запросов пока предыдущий не закончился добавить ожидание, например делать запрос когда человек 1 секунду ничего не вводил.

var timeout;
$('input').on('keyup', function(){
  clearTimeout(timeout);
  timeout = setTimeout(function(){
    request();
  });
});

3 вариант - хранить признак того, что надо сделать еще один запрос на случай, если человек что-то вводил пока выполнялся текущий запрос

var lateRequest = false,
    requestProcess = false;
$('input').on('keyup', function(){
  if (requestProcess) {
    lateRequest = true;
  } else {
    request();
  }
});
function request() {
  requestProcess = true;
  $.ajax({
    complete: function(){
      // обработка ответа...
      if (lateRequest) {
        lateRequest = false;
        request();
      } else {
        requestProcess = false;
      }
    }
  });
}

Только тут надо будет еще проверить ситуации, когда запросы могут слаться бесконечно один за одним))

Ну и можно совместить все три варианта

P.S. 4 вариант - добавить кнопку submit =)

READ ALSO
Зачем этот алгоритм и что он делает?

Зачем этот алгоритм и что он делает?

Есть кусок кода, я не понимаю, зачем он и как работаетПо идее функция getComponentTypeID() возвращает какой-то ID (зависящий от количества вызовов) на 1 больше...

117
как определить inline функцию?

как определить inline функцию?

Как определить встроилась ли функция или у нее свой адрес и реализация, как у не встраимовой функции? Компилятор может игнорировать инструкцию,...

85
Constexpr значение как non-type template parameter

Constexpr значение как non-type template parameter

Я пробовал сделать static_assert для одного конструктора сразу в std::enable_if, используя msvc

87
Ищу информацию по архитектуре игр серии Worms

Ищу информацию по архитектуре игр серии Worms

Меня интересует, как внутри организованы игры серии Worms

81