我对搜索字段有一个简单的限制,可以确保不是每个按键都作为查询发送,它在按键后等待300毫秒后才提交。如果在300毫秒之前未检测到另一次按键操作,则时钟将重置。
我在Vue中进行了如下设置:
<input v-model="search_string" placeholder="Search..." type="text" @keyup="searchThrottle();">
runSearch (type) {
do something....
}
searchThrottle () {
if (window.ajaxtimeout) clearTimeout(window.ajaxtimeout)
window.ajaxtimeout = setTimeout(this.runSearch, 300)
},
根据此行,其工作方式有所不同:window.ajaxtimeout = setTimeout(this.runSearch, 300)
例如,如果我通过一个参数使行为window.ajaxtimeout = setTimeout(this.runSearch('autocomplete'), 300)
,则每次按键都会运行搜索,而忽略超时。
为什么功能不同?
答案 0 :(得分:5)
如果将this.runSearch('autocomplete')
放在setTimeout
中,则runSearch
函数将立即执行,而不是在预期的300ms
之后执行。
因此,您可以将runSearch
函数的参数添加到setTimeout
初始化中:
setTimeout(this.runSearch, 300, 'autocomplete');
或者您可以使用闭包,但需要在之前存储this
:
var self = this;
setTimeout(function {
self.runSearch('autocomplete');
}, 300);
就像@JaromandaX在评论中提到的那样,您可以使用ECMAScript 6做同样的事情:
setTimeout(() => this.runSearch('autocomplete'), 300);
还有另一种使用.bind()
创建函数引用的方法,该方法将this
和其他参数传递给runSearch
函数。这也很好,但是对我来说有点
setTimeout(this.runSearch.bind(this, 'autocomplete'), 300);
答案 1 :(得分:2)
setTimeout(函数,毫秒,param1,param2,...)
在IE9和更早版本中不支持setTimeout函数的参数。要解决此问题,您可以使用currying。
var that = this;
myCustomSearch(type){
return function(){
that.runSearch(type)
}
}
setTimeout(this.myCustomSearch('autocomplete'), 300)
答案 2 :(得分:1)
因为setTimeout需要一个函数 reference 。如果您输入this.runSearch()
,它将立即执行。要创建函数引用并传递参数,请使用bind
:
window.ajaxtimeout = setTimeout(this.runSearch.bind(this, 'autocomplete'), 300)
如果您使用Lodash,它就具有throttle功能。
答案 3 :(得分:1)
在第一个版本中,您要告诉浏览器等待300毫秒,然后调用this.runSearch()
。
在第二个变体中,您将参数传递给函数,是告诉浏览器运行this.runSearch('autocomplete')
。
如果您希望在仍使计时器工作的同时将参数传递到this.runSearch
函数中,则可以将其包装在函数中:
function runDelayedSearch(){
this.runSearch('autocomplete');
}
window.ajaxtimeout = setTimeout(runDelayedSearch, 300)
您可以在ES6中使用以下命令更简洁地做到这一点:
window.ajaxtimeout = setTimeout(() => runSearch('autocomplete'), 300)
答案 4 :(得分:-1)
您可以使用如下绑定函数:
setTimeout(this.runSearch.bind(this, 'autocomplete'), 300)
这不会在实例化时执行功能