减少AJAX发出的服务器请求

时间:2014-07-10 15:52:44

标签: jquery ajax

我有一个滑块组件,它调用AJAX请求来根据滑块指向的值更新表。

在我的本地服务器上,没有实现延迟功能似乎很好,但是自从将我的代码部署到云服务后,我发现当发送到服务器时发送到服务器的请求数量会产生大量的延迟。用户正在滑动。

我目前的代码:

$( "#psi_slider" ).slider({
    range: "min",
    value:0,
    min:0,
    max:max_psi, 
    slide: function(event, ui) {
        update_results(json, get_values());
    }
});

有人能告诉我如何在请求之间实现计时器,即每秒发送一个请求吗?

1 个答案:

答案 0 :(得分:6)

此方案非常类似于用户在字段上键入并且您希望在用户键入时更新数据/提供的方案,但不一定每次用户按下键时。

这种情况有三种方法:

方法1:每次更新某些内容时都会更新

当某些事情发生变化时,这可能是一种可行的方法。意味着"用户按下一个键"但绝对不是当它意味着"滑块移动一点点"这是你的情况。

...

whenSomethingChanges : function(){
    updateData();
}

...

function updateData(){
    // Make your ajax call
}

Fiddle

方法2:等到事情停止变化,然后更新

也就是说,当用户停止键入或停止移动滑块一段时间后,请更新您的数据。在滑块的情况下,这种方法足以大幅减少Ajax调用量。然而,它有明显的缺点,如果用户不停止移动东西,他/她将不会看到他/她的行为的结果,并可能会感到沮丧。

var timeout = 500; // half a second
var scheduler = new Scheduler(updateData, timeout);

...

whenSomethingChanges: function(){
    scheduler.updateDataInAWhile();
}

...

function Scheduler(callback, timeout){

    this.callback = callback;
    this.timeout = timeout;
    this.updateDataTimeout = null;

    this.updateDataInAWhile = function(){

        if(this.updateDataTimeout){
            clearTimeout(this.updateDataTimeout);
        }

        var self = this;
        this.updateDataTimeout = setTimeout(function(){
            self.callCallback();
        }, this.timeout);
    };

    this.callCallback = function(){
        if($.isFunction(this.callback)){
            this.callback();
        }
    } 
}

function updateData(){
    // Make your ajax call
}

Fiddle

方法3:在事情不断变化时定期更新

标题说明了一切。这将限制Ajax调用的频率,同时以连续的方式向用户提供反馈。

var timeout = 500; // half a second
var scheduler = new Scheduler(updateData, timeout);

....

whenSomethingChanges: function(){
    scheduler.keepUpdating();
}

...

function Scheduler(callback, timeout) {

    this.callback = callback;
    this.timeout = timeout;
    this.currentlyUpdating = false;
    this.finalTimeout = null;

    this.keepUpdating = function(){
        if(!this.currentlyUpdating){
            this.startPeriodicUpdate();
        }

        if(this.finalTimeout){
            clearTimeout(this.finalTimeout);
        }
        var self = this;
        this.finalTimeout = setTimeout(function(){
                self.discontinueUpdates();
            }, this.timeout);
    };

    this.startPeriodicUpdate = function(){
        this.currentlyUpdating = true;        
        this.runPeriodicUpdate();
    };

    this.runPeriodicUpdate = function(){

        if($.isFunction(this.callback)){
            this.callback();
        }

        var self = this;
        if(this.currentlyUpdating){
            setTimeout(function(){
                self.runPeriodicUpdate()
            }, self.timeout);
        }
    };

    this.discontinueUpdates = function(){
        this.currentlyUpdating = false;
    };
}

Fiddle