首页 > 解决方案 > 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)为每个按键运行搜索,忽略超时。

为什么功能不同?

标签: javascriptvue.js

解决方案


如果您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);

有关 MDN 上的 setTimeout 的更多信息。


推荐阅读