我有一个文本框,每次用户输入一个字母时,我都会使用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
}
});
}
});
答案 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;
}
};
})($);