Jak okresowo odpalać żądanie AJAX?

113
<meta http-equiv="Refresh" Content="5">

Ten skrypt ponownie ładuje lub odświeża stronę co 5 sekund. Ale chcę to zrobić za pomocą jQuery i wywołania AJAX. Czy to możliwe?

user12345
źródło

Odpowiedzi:

281

Jak zauważyli inni, setInterval i setTimeout załatwią sprawę. Chciałem podkreślić nieco bardziej zaawansowaną technikę, której nauczyłem się z tego doskonałego filmu Paula Irisha: http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/

W przypadku zadań okresowych, które mogą zająć więcej czasu niż interwał powtarzania (np. Żądanie HTTP przy wolnym połączeniu), najlepiej nie używać setInterval(). Jeśli pierwsze żądanie nie zostało zakończone i rozpoczniesz kolejne, możesz skończyć w sytuacji, w której masz wiele żądań, które pochłaniają udostępnione zasoby i nawzajem głodują. Możesz uniknąć tego problemu, czekając na zaplanowanie następnego żądania, aż do zakończenia ostatniego:

// Use a named immediately-invoked function expression.
(function worker() {
  $.get('ajax/test.html', function(data) {
    // Now that we've completed the request schedule the next one.
    $('.result').html(data);
    setTimeout(worker, 5000);
  });
})();

Dla uproszczenia użyłem wywołania zwrotnego sukcesu do planowania. Wadą tego jest to, że jedno nieudane żądanie zatrzyma aktualizacje. Aby tego uniknąć, możesz zamiast tego użyć pełnego wywołania zwrotnego:

(function worker() {
  $.ajax({
    url: 'ajax/test.html', 
    success: function(data) {
      $('.result').html(data);
    },
    complete: function() {
      // Schedule the next request when the current one's complete
      setTimeout(worker, 5000);
    }
  });
})();
Drewish
źródło
3
Czy to nie jest jak rekurencyjne wywołanie funkcji? Jeśli tak, to czy można pozwolić mu działać w kółko przez długi czas, ponieważ jest rekurencyjny? może być przypadek nieskończonej rekurencji jak długo utrzymuje skutecznie wykonując ajax
Rahul Dole
1
Ponadto, jeśli używasz setTimeout, czy istnieje sposób na zatrzymanie tego wątku spoza tego bloku kodu? Podobnie jak w przypadku setInterval, możesz po prostu wywołać metodę clearInterval ().
Rahul Dole
16
@RahulDole to dobre pytanie, ale nie jest rekurencyjne. Nie jest wywoływana bezpośrednio z funkcji pracownika, więc stos nie będzie się powiększał. Po drugie, sprawdź dokumentację setTimeout (), a zobaczysz, że zwraca ona numeryczny identyfikator, który można przekazać do clearTimeout ().
drewish
7
@RahulDole, jeśli jesteś w chrome, pobaw się z console.trace (), aby zobaczyć stos wywołań funkcji. Funkcje wywoływane przez setTimeout () będą miały bardzo krótki stos i na pewno nie będą zawierały funkcji, która wywołała setTimeout ().
drewish
1
@Anupal po prostu utwórz nowe pytanie.
drewish
34

Tak, możesz użyć setTimeout()metody lub setInterval()metody JavaScript , aby wywołać kod, który chcesz uruchomić. Oto, jak możesz to zrobić za pomocą setTimeout:

function executeQuery() {
  $.ajax({
    url: 'url/path/here',
    success: function(data) {
      // do something with the return value here if you like
    }
  });
  setTimeout(executeQuery, 5000); // you could choose not to continue on failure...
}

$(document).ready(function() {
  // run the first time; all subsequent calls will take care of themselves
  setTimeout(executeQuery, 5000);
});
Tahbaza
źródło
1
Użyj po prostu setTimeout (executeQuery, 5000); zamiast setTimeout ('executeQuery ()', 5000); - jest krótszy i szybszy.
rsp
4

Możesz użyć setTimeoutlub setInterval.

Różnica polega na tym, że setTimeout wyzwala Twoją funkcję tylko raz, a następnie musisz ustawić ją ponownie. setInterval ciągle wyzwala wyrażenie, chyba że każesz mu się zatrzymać

Puneet
źródło
1

Wypróbowałem poniższy kod,

    function executeQuery() {
  $.ajax({
    url: 'url/path/here',
    success: function(data) {
      // do something with the return value here if you like
    }
  });
  setTimeout(executeQuery, 5000); // you could choose not to continue on failure...
}

$(document).ready(function() {
  // run the first time; all subsequent calls will take care of themselves
  setTimeout(executeQuery, 5000);
});

Nie działało to zgodnie z oczekiwaniami w określonym przedziale czasu, strona nie załadowała się całkowicie, a funkcja była wywoływana w sposób ciągły. Lepiej zadzwonić na setTimeout(executeQuery, 5000);zewnątrz executeQuery()w osobnej funkcji, jak poniżej,

function executeQuery() {
  $.ajax({
    url: 'url/path/here',
    success: function(data) {
      // do something with the return value here if you like
    }
  });
  updateCall();
}

function updateCall(){
setTimeout(function(){executeQuery()}, 5000);
}

$(document).ready(function() {
  executeQuery();
});

To działało dokładnie tak, jak powinno.

Srihari
źródło