如何在达到设置的时间之前覆盖设置超时?



所以我正在使用jquery进行自动完成搜索。在执行 ajax 函数之前,我必须设置延迟,因为我不想每次在文本框上键入时都用调用来锤击我的服务器。这是我的代码:

function searchVendor() {
setTimeout(searchVendor2, 5000);
}
function searchVendor2() {
var search = $('#inputVendor').val();
$.ajax({
type: 'POST',
url: '/getVendors',
data: {search: search},
dataType: 'json',
success: function(s) {
$('#inputVendor').autocomplete({source: s});
}
});
}

因此,函数searchVendoronkeyup执行

<input type="text" class="form-control input-sm" id="inputVendor" onkeyup="searchVendor()">

如果我键入 3 个字符(例如 sas),则函数searchVendor2执行 3 次。5 秒延迟有效,但它没有停止并覆盖之前的setTimeout

我想发生的是,如果我在文本框中键入一个字符,它将在 5 秒后执行,但是! 如果在 5 秒之前键入新字符,setTimeout将再次重置为 5 秒。只要用户在文本框上键入,setTimeout就会重置为 5 秒,并且只有在 5 秒过去而用户没有再次键入时才会执行。

感谢那些可以提供帮助的人!

首先,您需要将超时 id 保存在全局变量中,或者保存在稍后再次调用函数时可以访问的变量中。

现在,无论何时调用函数,首先清除超时(如果存在)。因此,您可以清除任何预先存在的超时,并在每次调用函数时设置一个新的超时。

var myTimeout;
function searchVendor() {
clearTimeout(myTimeout);
myTimeout = setTimeout(searchVendor2, 5000);
}
function searchVendor2() {
var search = $('#inputVendor').val();
$.ajax({
type: 'POST',
url: '/getVendors',
data: {search: search},
dataType: 'json',
success: function(s) {
$('#inputVendor').autocomplete({source: s});
}
});
}

涉及setTimeout()的其他答案很简单并且会起作用,但这是我建议使用实用程序库的少数几次之一,因为它们可以以用户明显的方式更进一步。

同样重要的是,我们避免重新发明轮子。在这种情况下,您想要的是一个去抖动或限制功能,以限制处理程序在给定时间范围内执行的次数。好的库还接受选项来调整处理程序的确切运行时间,这可能会影响应用的响应能力。

阅读有关去抖动和限制的更多信息。

对于您的用例,我推荐 Lodash 的_.throttle()leadingtrailing选项都设置为true.这将确保长文本条目仍将获得一些中间结果,同时尽可能快地获得结果(不必第一次等待计时器),并且仍然保证最终击键将触发新结果,并非所有去抖动设置都可以。

const handler = (evt) => {
console.log('I will talk to the server.');
};
const throttled = _.throttle(handler, 500, {
leading  : true,
trailing : true
});

然后将受限制的函数注册为事件侦听器。

<input type="text" class="form-control input-sm" id="inputVendor" onkeyup="throttled()">

当您想要停止超时时,必须清除它。 而不是仅仅这样做:

var timeoutId;
function searchVendor() {
timeoutId = setTimeout(searchVendor2, 5000);
}

你应该添加clearTimeout(timeoutId);,像这样:

var timeoutId;
function searchVendor() {
clearTimeout(timeoutId);
timeoutId = setTimeout(searchVendor2, 5000);
}

您可以使用autocompleteminLength,以便在用户开始键入时不会立即调用 API。

这是自动完成的参考

minLength:用户在执行搜索之前必须键入的最小字符数

$( "#inputVendor" ).autocomplete({
minLength: 3
});

如果您想要每次按键,如其他答案建议的那样,您可以使用clearTimeout来删除旧的超时。

var timeout;
function searchVendor() {
clearTimeout(timeout);
timeout = setTimeout(searchVendor2, 5000);
}

可以使用clearTimeoutclearInterval函数停止setTimeoutsetInterval函数,传递第一个函数生成的唯一标识符。例如,这里有一个小代码可以帮助您理解这一点:

var delay;
document.addEventListener("mousemove", function () {
callSetTimeout();
});
function callSetTimeout () {
if (!isNaN(delay)) { clearTimeout(delay); }
delay = setTimeout(function () {
console.log("do something");
}, 5000);
}

我更改了超时,但我检查了间隔

var goal={
cb: cb
,   timeout: (+new Date())+60000 //one minute from now
,   setInterval(function(){
if((+new Date())>goal.timeout){cb();}
})
};

现在我想增加、减少或重置超时?

goal.timeout-=1000;
goal.timeout+=1000;
goal.timeout=60000;

最新更新