如何限制ajax请求?

all*_*lis 16 javascript jquery

有几个div和处理程序在单击它们时发送ajax请求.我的问题是我不知道如何强迫我的处理程序不超过每30秒1个请求的限制.

感谢您的帮助!

Way*_*ett 34

优秀的Underscore.js具有节流功能.您传入要阻止的处理程序并返回相同功能的速率限制版本.

var throttled = _.throttle(someHandler, 100);
$(div).click(throttled);
Run Code Online (Sandbox Code Playgroud)

http://documentcloud.github.com/underscore/#throttle

这是我在自己的代码中使用的简化版本:

function throttle(func, wait) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        if (!timeout) {
            // the first time the event fires, we setup a timer, which 
            // is used as a guard to block subsequent calls; once the 
            // timer's handler fires, we reset it and create a new one
            timeout = setTimeout(function() {
                timeout = null;
                func.apply(context, args);
            }, wait);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

测试它的一个好方法是触发一堆滚动事件并观察处理程序日志到Firebug控制台:

document.addEventListener("scroll", throttle(function() {
    console.log("test");
}, 2000), false); 
Run Code Online (Sandbox Code Playgroud)

这是一个版本div,根据请求(需要jQuery)将s 上的点击事件限制为每30秒一次:

$("div").click(throttle(function() {
    // ajax here
}, 30000));
Run Code Online (Sandbox Code Playgroud)

  • _.throttle用于限制指定时间内的函数调用次数。如果要对速率进行限制,即将请求排队,并确保它们仅每X秒运行一次,那么您将需要另一种解决方案(在我的回答中提供) (2认同)

Mat*_*dan 19

如果你想率限制,那么不幸的是,underscore.js提供的_.throttle方法不是你的解决方案.Throttle将简单地确保您的方法永远不会被调用超过X秒,因此所有后续函数调用将被忽略,直到该时间段过去.

如果你想限速,这样你就不会每秒调用你的函数超过X次,但是不要完全失去那些函数调用,那么你需要一个完全不同的解决方案.

我在https://gist.github.com/1084831写了一个下划线扩展名

您可以在http://jsbin.com/upadif/8/edit#preview上看到一个工作示例

  • 谢谢 - 这就是*我*正在寻找的东西.(用例是基于单个用户操作触发对第三方,速率受限API的多个查询.) (6认同)

Moh*_*mad 11

在每个ajax请求之后创建一个boolean canFireRequest或者其他标志并将其设置为false.然后创建一个30秒的时间跨度,使其恢复为真; 在每个新请求之前检查标志的值.

这是一个粗略的例子:

if ($(this).data('canFireRequest')) {
    // Ajax request goes here
    $(this).data('canFireRequest', false);
}

setTimeout(function() {
    $(this).data('canFireRequest', true)
}, 30000);
Run Code Online (Sandbox Code Playgroud)

  • @Mathew,问题并未表明是否需要对后续请求进行排队或只是忽略它们.这是否是一个好的解决方案取决于您的需要.例如,SO允许您每5秒进行一次评论投票.他们不排队后续的投票请求.他们只是忽略它们并为您提供错误消息.同样,这取决于您的需求. (6认同)
  • 我想,setTimeout的第二个参数应该是30000,持续30秒 (2认同)