在时间范围内防止对同一URL进行多次AJAX调用

时间:2015-04-12 22:04:35

标签: javascript jquery ajax

我有一个应用程序想要获取有关地图上每个标记的信息。

每个标记都有一个类,例如" car"或"行人"。

该应用程序(通过jQuery){&#34; http://myserver/info/&#34; {<1}}调用。

但是,由于多个标记可能具有相同的类,因此服务器最终可能会遇到许多请求。

因此,我希望汇集在指定时间范围内(可能是5秒左右)发生的请求,以便只发出一个请求,但getJSON的每个调用实例都不知道它

我的想法是将getJSON包装在另一个函数中,该函数将URLS存储在hashmap / dictionary中,并为每个请求者存储promise。返回数据时,将履行承诺。

我问,有没有一种标准的方法可以做到这一点(解析一个AJAX请求,就像这样)?

3 个答案:

答案 0 :(得分:2)

我创造了一些可能对你有帮助的东西(25分钟^^);它是一个超时经理:

var requestsPool = {
    requests: {}, //list of urls
    timeout: 5000, //In milliseconds
    add: function(url) {
        if(requestsPool.exists(url)) return false; //check if url is already present in the pool
        requestsPool.requests[url] = setTimeout(function(u) {
            requestsPool.remove(u);
        }.bind(this, url), requestsPool.timeout); //Defining the timeout
        return true;
    },
    exists: function(url) {
        return requestsPool.requests[url]; //Return the Timeout ID if present or undefined
    },
    remove: function(url) {
        return delete requestsPool.requests[url]; //return true almost always @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
    },
    cancel: function(url) {
        clearTimeout(requestsPool.requests[url]); //cancel the timeout
        return requestsPool.remove(url); //remove the url form the pool
    }
}

$(anchor).click(function() {
    if(requestsPool.exists(anchor.href)) {
        // If cooldown is present
    } else {
        $.getJSON(anchor.href, function(data) {
            requestsPool.add(anchor.href);
        });
    }
})

答案 1 :(得分:2)

  

我的想法是将getJSON包装在另一个函数中,该函数将URLS存储在一个hashmap / dictionary中,并为每个请求者存储promises

是的,这是一个好主意。它可能看起来像这样:

var debouncedGet = (function() {
    var pool = {};
    return function get(url) {
        if (!pool[url]) {
            pool[url] = $.getJSON(url);
            setTimeout(function() {
                pool[url] = null;
            }, 5000); // you might want to move this into a `pool[url].always(…)` callback
                      // so the timer starts when the request returned
         }
         return pool[url];
     };
 }());

答案 2 :(得分:1)

这是我的出价:

(function(window,$,undefined){
    'use strict';

    var cache = {},
        timeout = 5e3;

    // Use like traditional $.getJSON
    $.getJSON = function(url,data,callback){
        if ($.isFunction(data)){
            callback = data;
            data = undefined;
        }

        // Establish a cache key so we can re-reference existing
        // requests to subsequent ones (within the timeout window).
        var cacheKey = url;
        if (cache[cacheKey]){
            // This is an existing request; Simple add the callback
            // onto the promise and return it.
            return cache[cacheKey].done(callback);
        } else {
            // This is a new request. Build up a new request,
            // attach the callback to the promise, and also add
            // a couple cleanup methods for disposing the cache
            // when appropriate.
            cache[cacheKey] = $.ajax($.extend({
                url: url,
                type: 'get',
                dataType: 'json',
                data: data,
            }, $.isPlainObject(url) && url))
            .done(callback)
            .always(function(){
                delete cache[cacheKey];
            });
            setTimeout(function(){
                // TODO: Probbaly want to store a reference to
                // this timeout and clear it in the .always (to
                // avoid race condition between .always firing
                // and new request coming in but not returning yet)
                cache[cacheKey] && delete cache[cacheKey];
            }, timeout);
            return cache[cacheKey];
        }
    };
})(window,jQuery);

而且,FWIW,一个jsFiddle:http://jsfiddle.net/ajtbdxt7/