减少由AJAX发出的服务器请求

3
我有一个滑块组件,它调用 AJAX 请求来根据滑块所指的值更新表格。
在我的本地服务器上,没有实现延迟函数似乎很好,但是自从将代码部署到云服务后,我注意到当用户滑动时发送到服务器的请求数量会产生显着的延迟。
我的当前代码:
$( "#psi_slider" ).slider({
    range: "min",
    value:0,
    min:0,
    max:max_psi, 
    slide: function(event, ui) {
        update_results(json, get_values());
    }
});

请问如何实现请求间的定时器,例如每秒发送一个请求?


在你的情况下,逐个获取数据与在第一次请求时获取所需所有数据相比有什么优势? - Diodeus - James MacFarlane
我的客户指定表格必须在用户滑动时更新,以提供更好的用户体验。我之前将更新绑定到 changed:,但那还不够好! - Halfpint
1
仅在滑块停止时更新。 - Kevin B
3
用户体验和AJAX实现并不需要耦合在一起。你可以提前获取所有数据,并实现自己的时间机制来满足用户体验。 - Diodeus - James MacFarlane
你能否保留效果,直到停止才将数据推送到服务器? - Kevin B
显示剩余4条评论
1个回答

6

这种情况类似于用户在字段上键入内容时,您希望在用户输入时更新数据/提供数据,但并非每次用户按键都需要更新。

有三种方法可以解决这种情况:

方法一:每次更改时都进行更新

当“某些内容被更改”意味着“用户按下一个键”时,这可能是可行的方法,但对于您的情况——“滑块移动了一点”,则明显不可行。

...

whenSomethingChanges : function(){
    updateData();
}

...

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

方法二:等待事物停止变化,然后更新

即当用户停止输入或停止移动滑块一段时间后,更新您的数据。在滑块的情况下,这种方法足以大幅减少Ajax调用量。但是,它显然的缺点是,如果用户不停地移动元素,则无法看到其操作结果,可能会感到沮丧。

Fiddle

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
}

第三种方法:定期更新,当事物不断变化时

标题已经说明了一切。这将限制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


方法三正是我所寻找的。 - Halfpint

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接