Jquery ajax请求,等待最新请求完成

时间:2010-01-05 19:24:59

标签: jquery ajax httpwebrequest

我有一个文本框,每次用户输入一个字母时,我都会使用ajax请求进行搜索,并为用户显示“实时”结果。通常,当用户键入字母时,请求所花费的时间比用户输入新字母所需的时间长,因此在第一个字母结束之前会发出新的请求。如果第一个可以在我做下一个请求之前结束会好得多。如果最新的请求已经结束,是否有一个很好的方法只能提出新请求?

这是我的jquery代码:

$("#MyTextBox").change(function() {
    if (this.value.length > 2) {
        $.ajax({
            type: "GET",
            url: "http://www.domain.com/Service.svc/Search?keyword=" + this.value,
            dataType: "json",
            success: function(data) {
                //here I have some code that shows the result for the user
            }
        });
    }
});

5 个答案:

答案 0 :(得分:10)

您可以创建一个包含true或false的布尔值,具体取决于是否已发生请求。在启动请求时将其设置为true,并在回调函数中将其设置为false。

var request_in_process = false;
$("#MyTextBox").change(function() {
    if (this.value.length > 2 && !request_in_process) {
        request_in_process = true;
        $.ajax({
            type: "GET",
            url: "http://www.domain.com/Service.svc/Search?keyword=" + this.value,
            dataType: "json",
            success: function(data) {
                request_in_process = false;
                //here I have some code that shows the result for the user
            }
        });
    }
});

答案 1 :(得分:8)

您可以中止AJAX请求。将请求作为变量跟踪,并在重新发起请求之前中止它。

var request = $.ajax({ ... });
request.abort();

这具有对用户输入更敏感的附加优势。如果用户在启动第一个请求后输入了更多内容,他可能不再关心第一组结果了。中止并重新创建AJAX请求意味着用户可以获得更好的结果集。

答案 2 :(得分:0)

您可以使用ajaxComplete,以便在发出新请求之前知道请求何时完成。

您可以将其与bind / unbind结合使用,以便手动添加更改事件,然后在ajax请求启动时解除绑定,并在ajax请求完成时反弹。

答案 3 :(得分:0)

正如ceejayoz已经提到的,你应该中止之前的请求。 (等待请求会让用户发疯,如果他们无法按照自己的意愿打字。并且更喜欢旧请求而不是新请求会使结果过时。)那么:

var request = null;
//...       
$("#MyTextBox").change(function() {
    if (this.value.length > 2) {
        if (request && request.abort)
            request.abort();
        request = $.ajax({
            type: "GET",
            url: "http://www.domain.com/Service.svc/Search?keyword=" + this.value,
            dataType: "json",
            success: function(data) {
            //here I have some code that shows the result for the user
            request = null;                
        });
    }             
});

答案 4 :(得分:0)

这里的实施稍微强一些。基本上我们将ajax对象(即promise对象)保存到闭包中,以便后续调用可以查看它。如果下一次调用发现请求状态为挂起,则它将向该挂起请求添加回调,而不是生成新请求。 jQuery将按照添加的相同顺序触发所有回调。但是,同一个调用者可能会一次又一次地尝试创建请求。为了防止这种情况,我添加了callerId参数。如果同一个调用者在先前的请求仍处于未决状态时再次发出请求,则我们只是忽略该请求。为了完整性,我还添加了cachedValues。因此,如果已经提出了ajax请求,我们就不再重复了。

var ajaxRequestor = function ($) {
    "use strict";

    //privates
    var cahedValues = {};
    var currentAjaxRequest, callers;

    //public interface
    return {
        getData: function (callerId, onGet, onFail, forceRefresh) {
            if (forceRefresh || !cahedValues.myData) {

                //If there is a pending request, don't start new one
                if (!currentAjaxRequest || currentAjaxRequest.state() != "pending") {
                    currentAjaxRequest = $.getJSON("data/MyData.json");
                    callers = {};   //list of callers waiting for request
                }

                //if this caller is not in the list, add it and queue up its callbacks to existing request
                if (!callers[callerId]) {   
                    callers.callerId = callerId;

                    currentAjaxRequest.done(function (data, textStatus) {
                        cahedValues.myData = data;
                        onGet(data);
                    });

                    currentAjaxRequest.fail(function (jqxhr, textStatus, error) {
                        if (!!onFail) {
                            onFail(error);
                        }
                        else throw error;
                    });
                }
            }
            else {
                onGet(cahedValues.myData);
            }
        },

        invalidateMyData: function () {
            delete cahedValues.myData;
        }
    };
})($);