setInterval в jQuery происходит слишком быстро - PullRequest
2 голосов
/ 16 апреля 2011

Я использую setInterval, и иногда это происходит "слишком быстро".Вот как это выглядит:

setInterval(function() {
    //here comes ajax functions and so on. 
}, 1000);   

Иногда setInterval происходит быстрее, чем все эти функции ajax, и дает мне два сообщения вместо одного.Какое решение для этого?

Ответы [ 6 ]

10 голосов
/ 16 апреля 2011

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

setInterval отлично подходит для некоторых вещей, но не для чего-либо, где вы собираетесь смешивать другие асинхронные вещи с ним. Вместо этого используйте идиому «rescheuling setTimeout»:

setTimeout(doSomething, 1000);
function doSomething() {
    $.ajax("your_url", {
        success: function() {
            // Do something here

            // Do something else here
        },
        complete: function() {
            // Previous run complete, schedule the next run
            setTimeout(doSomething, 1000);
        }
    });
}

... потому что, в конце концов, ваш ajax вызов может занять больше секунды.

Если это не та проблема, с которой вы столкнулись, я думаю, ваш код выглядит примерно так:

setInterval(function() {
    $.ajax("your_url", {
        success: function() {
            // Do something here
        }
    });

    // Do something else here
}, 1000);

... и вам интересно, почему код "Сделай что-то еще здесь" выполняется перед кодом "Делай что-то здесь". Если это так, то причина в том, что по умолчанию ajax-вызовы асинхронны . Ваш звонок $.ajax начинает звонок, но это все; тогда весь ваш другой код выполняется до того, как произойдут обратные вызовы (или ошибки).

Исправление, конечно, состоит в том, чтобы не делать ничего еще на верхнем уровне, который зависит от обратного вызова успеха:

setInterval(function() {
    $.ajax("your_url", {
        success: function() {
            // Do something here

            // Do something else here
        }
    });

}, 1000);
2 голосов
/ 16 апреля 2011

С jQuery 1.5.x вы можете использовать Then () для отложенного объекта. Это хороший способ сказать, как только вы закончите, тогда () сделайте это. Вы также можете использовать опцию When (), чтобы дождаться завершения более чем одного ajax-запроса.

Эти две вещи очень крутые и мощные.

http://api.jquery.com/deferred.then/

http://api.jquery.com/jQuery.when/

1 голос
/ 18 августа 2011

Я думаю, что проблема здесь из-за объема.Даже если метод успешно запущен.

С похожей проблемой я могу использовать это, чтобы исправить:

setTimeout(function(){
    load1();
}, 5000); 

function load1 () {
    console.log('loaddd1..');
    setTimeout(load2(), 4000); 
}

function load2 () {
    setTimeout(function(){
    console.log('end load2');
}, 4000); 
1 голос
/ 16 апреля 2011

Установите флаг, который указывает, что выборки ajax находятся в процессе. Когда все выборки Ajax завершены, снимите флажок. В верхней части функции setInterval немедленно вернитесь, если установлен флаг.

1 голос
/ 16 апреля 2011

Лучше не использовать setInterval, но каждый раз устанавливать новый setTimeout. Например:

setTimeout(function ajaxStuff() {
    // here comes ajax functions and so on.

    setTimeout(ajaxStuff, 1000);
}, 1000);

Конечно, если функции внутри являются асинхронными, как обычно это делают запросы AJAX, вызов setTimeout все равно будет приходить слишком рано. Вам нужно будет написать код, который вызывает setTimeout, когда запросы будут выполнены. $.when помогает вам в этом, поскольку $.ajax и другие методы jQuery AJAX реализуют $.Deferred:

setTimeout(function ajaxStuff() {
    $.when(
        $.ajax({
            url: 'ajax1.htm'
        }),
        $.ajax({
            url: 'ajax2.htm'
        }),
        $.ajax({
            url: 'ajax3.htm'
        })
    ).done(function() {
        setTimeout(ajaxStuff, 1000);
    });
}, 1000);
0 голосов
/ 24 октября 2018

имел эту проблему, и clearInterval не работал.

убедитесь, что setInterval вызывается только один раз, обернув его в оператор if:

var interval;

if (typeof(interval) === 'undefined') {
  interval = setInterval(actFakeData,3000);
}

Для меня также было полезно назначить setInterval переменной и console.log, чтобы вы могли видетьзначение во всем вашем коде.для меня, когда это ускорялось, это увеличивалось в числовом значении вместо сброса, пока я не обернул это в это.

...