javascript - setTimeout 的行为因传递的函数参数而异
问题描述
我对搜索字段有一个简单的限制,以确保不是每个按键都作为查询发送,它会在按键后等待 300 毫秒,然后再提交。如果在 300ms 结束之前检测到另一个按键,则时钟重置。
我在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)
为每个按键运行搜索,忽略超时。
为什么功能不同?
解决方案
如果您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
。这也很有效,但这对我来说有点hacky 。由于维护和可读性,我个人不喜欢这种做法。但是为了得到一个最完整的答案,我也添加了这个例子(第一篇文章来自@BrotherWoodrow 关于这个):
setTimeout(this.runSearch.bind(this, 'autocomplete'), 300);