Как заставить jQuery постоянно запрашивать один и тот же HTTP-запрос GET - PullRequest
1 голос
/ 22 декабря 2010

Я реализую программное обеспечение, которое считывает состояние системы с помощью jQuery, используя $. GetJSON .

Идея состоит в том, что я отображаю данные в реальном времени в браузере и хочу обновлять данные как можно чаще. Сервер также работает на локальном хосте, поэтому теоретически у меня должна быть очень низкая задержка (не менее 50 мс, даже менее 20).

Но вопрос в следующем: как я могу реализовать getJSON с jQuery, чтобы запрос HTTP GET автоматически отправлялся сразу после завершения предыдущего запроса?

В моей текущей реализации я определил функцию обновления:

function updateSimulation() {       
   $.getJSON('/simulation/', function(data) {
      // ..parse data here
   });    
}

И добавляется обратный вызов один раз каждые 50 мс:

document.simulationIntervalId = setInterval( "updateSimulation()", 50 );

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

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

Но, как всегда, все комментарии и ответы очень ценятся!

Ответы [ 6 ]

2 голосов
/ 22 декабря 2010

Во-первых, при использовании setInterval() или setTimeout(), не передавайте метод в виде строки, так как это вызывает печально известную eval(), что является плохой практикой кодирования. Скорее передайте метод так: setInterval(updateSimulation, 50);

Чтобы убедиться, что запрос ajax завершен до того, как будет отправлен другой, используйте setTimeout(), чтобы вызвать метод updateSimulation() только один раз, а затем в случае успеха jjery ajax снова вызовите updateSimulation().

2 голосов
/ 22 декабря 2010

Почему бы вам не вызвать updateSimulation для функции успеха (второй параметр $ .getJSON)?

Он выполнит запрос после завершения предыдущего.

1 голос
/ 22 декабря 2010

Вы также можете использовать setInterval с нужным периодом (например, 50 мс) и добавить индикатор, чтобы узнать, завершился ли предыдущий запрос. Этот индикатор не обязательно должен быть в гобелене.

function updateSimulation() {
   if (!requesting) {
      requesting = true;
      $.getJSON('/simulation/', function(data) {
         requesting = false;
      });
   }
}

var requesting = false;
setInterval ('updateSimulation', 50);

Где пространство имен - это объект, который вы используете.

1 голос
/ 22 декабря 2010

вместо этого используйте setTimeout и вызывайте его по возвращении прецедентного вызова. Он будет работать через 50 мс после возврата (кстати, 50 мс слишком мал для AJAX, примерно 500 мс или 1000)

Вы также можете добавить отметку времени к отправленным данным и сравнить ее с последним известным временем ожидания

function updateSimulation() {               
   $.getJSON('/simulation/', function(data) {
         window.setTimeout(updateSimulation, 500 );

         if (data.sent > last_data_sent){
           // use data
           last_data_sent = data.sent

         }

   });              
}
1 голос
/ 22 декабря 2010

Сначала проанализируйте и используйте данные, затем выполните отложенный вызов

Используйте взамен window.setTimeout() и снова введите другой после завершения обработки текущего.Таким образом, не будет перекрытия .

function updateSimulation() {
   $.getJSON('/simulation/', function(data) {
      // ..parse data here
      window.setTimeout(updateSimulation, 250);
   });
}

Настройте время по своему усмотрению ...

0 голосов
/ 22 декабря 2010

2) звучит хорошо, но 50 мс немного быстрее. Я не думаю, что Сервер понравится.

...