Javascript setTimeout不延迟函数调用,单位为$。每个

Javascript setTimeout不延迟函数调用,单位为$。每个,javascript,jquery,ajax,get,settimeout,Javascript,Jquery,Ajax,Get,Settimeout,我在我的网站上有几个div,我想一个一个地更新。为了避免一次向服务器发送200多个请求的垃圾邮件,我希望每个请求延迟1秒 我尝试的是: var $tourBox = $('.tour-box'); $tourBox.each(function () { var $box = $(this); setTimeout(function () { getUpdate($box); }, 1000); }); 更新功能: function getUpdate($

我在我的网站上有几个div,我想一个一个地更新。为了避免一次向服务器发送200多个请求的垃圾邮件,我希望每个请求延迟1秒

我尝试的是:

var $tourBox = $('.tour-box');
$tourBox.each(function () {
    var $box = $(this);
    setTimeout(function () {
        getUpdate($box);
    }, 1000);
});
更新功能:

function getUpdate($box) {

    var $so = $box.attr('data-so');
    var $url = $('#ajax-route-object-status').val();
    $.get($url, {
        so: $so
    }).success(function (data) {
        var $bg = 'bg-gray';
        if (data.extra.isStarted === true && data.extra.isFinished === false) {
            $bg = 'bg-orange'
        }
        if (data.extra.isStarted === true && data.extra.isFinished === true) {
            $bg = 'bg-green'
        }
        if (data.extra.isLate === true && data.extra.isFinished === false) {
            $bg = 'bg-red'
        }
        $box.removeClass('bg-gray').removeClass('bg-green').removeClass('bg-orange').removeClass('bg-red').addClass($bg);
    });
}
在Chrome-Dev-->网络中,它显示所有加载为挂起的,然后逐个加载,但不包括延迟:


正如您可以看到的,在3907和3940之间,只有半秒的延迟。即使我有5000的超时,这也不会改变

您的for each同时调用所有超时。它不是在每次调用之间等待一秒钟。因此,有数千个对象计划调用
getUpdate($box)一秒钟后

您可以做的是增加每次迭代的超时时间

var $tourBox = $('.tour-box');
var delay = 1000;
$tourBox.each(function () {
    var $box = $(this);
    setTimeout(function () {
        getUpdate($box);
    }, delay);
    delay += 1000;
});
这将导致您的第一个超时在1秒后触发,第二个超时在两秒后触发,依此类推。

早在2008年,我就写过,这正是您想要的。它基本上是对
$的替换。each()
$(…)。each()
占用一个时间间隔,因此调用回调时每个元素的延迟量为:

jQuery.slowEach = function( array, interval, callback ) {
    if( ! array.length ) return;
    var i = 0;
    next();
    function next() {
        if( callback.call( array[i], i, array[i] ) !== false ) {
            if( ++i < array.length ) {
                setTimeout( next, interval );
            }
        }
    }
};

jQuery.fn.slowEach = function( interval, callback ) {
    jQuery.slowEach( this, interval, callback );
};

关于这段代码需要注意的一点是,它一次只使用一个计时器,而不是一次调用数百个
setTimeout()
来启动多个计时器。这使得系统资源更容易使用。

逐个调用可能是避免类似垃圾邮件请求的另一种解决方案。 在这种情况下,这可能是一个解决方案:

$(document).ready(function(){

    var $tourBox = $('.tour-box'),
        curIndex = 0,
        totalBox = $tourBox.length,
        url = $('#ajax-route-object-status').val(),


    function getUpdate(){

        var $box = $tourBox.get( curIndex );

        if ( typeof $box === 'undefined'){
            // No more box to process
            return; // exit
        }

        var $so = $box.attr('data-so');

        $.get($url, {
            so: $so
        }).success(function (data) {
            var $bg = 'bg-gray';
            if (data.extra.isStarted === true && data.extra.isFinished === false) {
                $bg = 'bg-orange'
            }
            if (data.extra.isStarted === true && data.extra.isFinished === true) {
                $bg = 'bg-green'
            }
            if (data.extra.isLate === true && data.extra.isFinished === false) {
                $bg = 'bg-red'
            }
            $box.removeClass('bg-gray').removeClass('bg-green').removeClass('bg-orange').removeClass('bg-red').addClass($bg);
        }).always(function(){

            // Increment index to process
            curIndex++;

            // Finished either with success or failed
            // Proceed with next
            getUpdate();
        });       
    }
});

“每个1”是什么意思?你的意思是每一个请求都会在1秒的时间间隔内发出,还是所有请求都会在1秒后发出?因为你的代码就是这么做的<代码>设置超时
不会暂停javascript执行。您的代码所做的是设置所有get请求在一秒钟后按预期工作的回调都假定是这样工作的。为了更好地理解回调函数的工作原理,请看一看。这对于较小的数组来说是可行的,但在进行大量的
setTimeout()
调用时应该谨慎。只要在任何时候只有一个
setTimeout()
处于活动状态,就可以轻松完成此任务。不要以越来越大的延迟启动大量
setTimeout()
调用,只需对每个调用使用相同的延迟,但在处理上一个调用后启动一个新的
setTimeout()
$(document).ready(function(){

    var $tourBox = $('.tour-box'),
        curIndex = 0,
        totalBox = $tourBox.length,
        url = $('#ajax-route-object-status').val(),


    function getUpdate(){

        var $box = $tourBox.get( curIndex );

        if ( typeof $box === 'undefined'){
            // No more box to process
            return; // exit
        }

        var $so = $box.attr('data-so');

        $.get($url, {
            so: $so
        }).success(function (data) {
            var $bg = 'bg-gray';
            if (data.extra.isStarted === true && data.extra.isFinished === false) {
                $bg = 'bg-orange'
            }
            if (data.extra.isStarted === true && data.extra.isFinished === true) {
                $bg = 'bg-green'
            }
            if (data.extra.isLate === true && data.extra.isFinished === false) {
                $bg = 'bg-red'
            }
            $box.removeClass('bg-gray').removeClass('bg-green').removeClass('bg-orange').removeClass('bg-red').addClass($bg);
        }).always(function(){

            // Increment index to process
            curIndex++;

            // Finished either with success or failed
            // Proceed with next
            getUpdate();
        });       
    }
});