如何在setTimeout达到设定的时间之前覆盖它?

时间:2017-05-25 05:45:11

标签: javascript jquery settimeout

所以我正在使用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
        });

  }
 });

}

所以函数searchVendor在keyup上执行

<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秒钟后才会执行,而用户不会再次输入。

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

5 个答案:

答案 0 :(得分: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
        });

  }
 });

}

答案 1 :(得分:2)

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

我们避免重新发明轮子也很重要。在这种情况下,您需要的是 debounce throttle 函数,以限制处理程序在给定时间跨度内执行的次数。好的库还接受在您的处理程序运行时调整的选项,这会影响应用程序的响应性。

Read more about debouncing and throttling

对于您的使用案例,我建议将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()">

答案 2 :(得分:1)

如果要停止它,必须清除超时。

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

你可以用它来停止间隔:

clearTimeout(timeoutId);

在这里:

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

答案 3 :(得分:1)

您可以使用minLength autocomplete,以便在用户开始输入时不会立即调用api。

Here is the reference from autocomplete

minLength:用户在执行搜索前必须输入的最少字符数

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

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

var timeout;

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

答案 4 :(得分:0)

<form name="myform" action=""> <label for="select_value">Select Number</label> <select name="select_value"> <option value="0">0</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> </select> <br> <label for="radio_value">Select Position</label> <input type="radio" name="radio_value" value="First">First <input type="radio" name="radio_value" value="Second">Second <input type="radio" name="radio_value" value="Third">Third <input type="radio" name="radio_value" value="Fourth">Fourth <input type="radio" name="radio_value" value="Fifth">Fifth </form>setTimeout函数可以使用setIntervalclearTimeout函数停止,传递第一个生成的唯一标识符。例如,这里有一个小代码可以帮助您理解这一点:

clearInterval