Запросы Ajax и условия гонки (на стороне клиента и сервера) - PullRequest
2 голосов
/ 07 сентября 2011

Давайте представим ситуацию, когда мы отправляли два одинаковых (почти похожих) асинхронных ajax-запроса на сервер один за другим.Из-за задержки в сети второй запрос был выполнен перед первым запросом.

Ajax request #1: /change/?object_id=1&position=5
Ajax request #2: /change/?object_id=1&position=6

В результате у нас object_id=1 позиция установлена ​​на position=5, но мы хотим position=6, потому что Ajax request #2 быловыполняется после Ajax request #1 нами.

Каков наилучший способ избежать этого на стороне сервера и на стороне клиента?

Ответы [ 3 ]

1 голос
/ 07 сентября 2011

Вы беспокоитесь о гоночных условиях одного и того же клиента или нескольких клиентов?

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

Я не уверен, как бы вы справились с несколькими клиентами с несинхронизированными часами ...

0 голосов
/ 07 сентября 2011

На сервере:

  • Построить таблицу запросов для сопоставления идентификатора запроса с отметкой времени
  • Записать любой запрос на сервер, ожидать, что все запросы приходят с отметкой времени
  • Если какой-либо запрос выходит из строя (например, позиция 6 предшествует 5)
    • Проверьте таблицу запросов, если это более ранний запрос (отметка времени), то не обрабатывайте запрос и отправляйте флаг игнорирования
  • Если все в порядке
    • Это нормально, действуйте как обычно, и нет необходимости отправлять приказ игнорирования

На клиенте:

  • Когда запрос возвращается, установите флажок игнорирования.Если это там.Ничего не делайте с клиентом
  • В противном случае действуйте как обычно, обрабатывая данные

Обратите внимание, что для этой реализации, которую я предложил, требуется отправлять данные туда и обратно (например, JSON).), а не код представления (например, фрагмент HTML), поскольку вам нужно будет проверить флаг игнорирования на стороне клиента.

Этот ответ аналогичен тому, что @Farray предлагает для использования отметки времени.

0 голосов
/ 07 сентября 2011

В подобных ситуациях я обычно ставлю проверку в своем обработчике успеха, чтобы убедиться, что возвращаемое значение все еще является тем, которое я хочу. Это потребует отправки параметра, который вы ищете, в объекте результатов.

Например:

var query = $('input').val();

$.get('/search', { query: query }, function(res) {
  if(res.query == $('input').val()) {
    //show search results
  }
});

Я не знаю подробностей вашего варианта использования, но этот общий шаблон должен помочь.

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