代码之家  ›  专栏  ›  技术社区  ›  Craig Ward

根据传递的函数参数,setTimeout的行为不同

  •  1
  • Craig Ward  · 技术社区  · 6 年前

    我对搜索字段有一个简单的限制,为了确保不是每个键都作为查询发送,它在提交前等待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) 搜索针对每个按键运行,忽略超时。

    为什么功能不同?

    5 回复  |  直到 6 年前
        1
  •  5
  •   eisbehr    6 年前

    如果你 this.runSearch('autocomplete') 在你 setTimeout , the runSearch 函数将立即执行,而不是在预期的 300ms .

    所以您可以为您的 搜索引擎 函数到 设置超时 初始化:

    setTimeout(this.runSearch, 300, 'autocomplete');
    

    或者你可以使用一个闭包,但需要存储 this 之前:

    var self = this;
    setTimeout(function {
        self.runSearch('autocomplete');
    }, 300);
    

    正如@jaromandax在评论中提到的那样,使用ecmascript 6可以缩短同样的操作:

    setTimeout(() => this.runSearch('autocomplete'), 300); 
    

    还有另一种方法,使用 .bind() 要创建函数引用,则 以及 搜索引擎 功能。这个也很好用,但感觉有点 哈奇 对我来说。我个人不喜欢这个apraoch,因为它具有维护性和可读性。但为了得到最完整的答案,我也添加了这个例子( 第一个帖子来自@Brotherwoodrow ):

    setTimeout(this.runSearch.bind(this, 'autocomplete'), 300);
    

    More information about setTimeout on MDN.

        2
  •  2
  •   Vladu Ionut    6 年前

    设置超时(函数,毫秒,参数1,参数2,…)

    IE9和更早版本不支持setTimeout函数的参数。为了解决这个问题,你可以用货币。

    var that = this;
        myCustomSearch(type){
            return function(){
            that.runSearch(type)
            }
        }
    
    
        setTimeout(this.myCustomSearch('autocomplete'), 300)
    
        3
  •  1
  •   Brother Woodrow    6 年前

    因为setTimeout需要一个函数 参考 . 如果你放 this.runSearch() 它将立即被执行。要创建函数引用并传递参数,请使用 bind :

    window.ajaxtimeout = setTimeout(this.runSearch.bind(this, 'autocomplete'), 300)
    

    如果你使用罗达什,它有一个 throttle 为此目的发挥作用。

        4
  •  1
  •   Sean D    6 年前

    在第一个变体中,您告诉浏览器等待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)

        5
  •  -1
  •   G1.3    6 年前

    您可以使用如下绑定函数:

    setTimeout(this.runSearch.bind(this, 'autocomplete'), 300)
    

    这不会在实例化时执行函数