尝试向 jQuery AJAX 请求添加延迟

Posted

技术标签:

【中文标题】尝试向 jQuery AJAX 请求添加延迟【英文标题】:Trying to add delay to jQuery AJAX request 【发布时间】:2012-07-03 17:41:08 【问题描述】:

我正在尝试延迟 AJAX 请求,以便在输入单元格的最后一次键入后 2-3 秒发送出去。 到目前为止,我已经设法延迟了请求,但在 2-3 秒后,我收到了针对该字段中的每个 keyup 发送的一个请求... 如何让 jQuery 取消第一个键并只发送最后一个键? 这是到目前为止的代码:

$('#lastname').focus(function()
          $('.terms :input').val(""); //clears other search fields
).keyup(function()
    caps(this); //another function that capitalizes the field
    $type = $(this).attr("id"); // just passing the type of desired search to the php file
        setTimeout(function() // setting the delay for each keypress
                ajaxSearchRequest($type); //runs the ajax request

        , 1000);
);

上面的代码等待 1 秒,然后根据按键发送 4-5 个 AJAX 请求。 我只想在最后一个 keyup 之后发送一个 我在 *** 中找到了一些类似的使用 javascript 的解决方案,但由于我的编程知识很少,我无法将它们实施到我的项目中。

[已解决] 最终的工作代码,感谢@Dr.Molle:

$('#lastname').focus(function()
          $('.terms :input').val("");
).keyup(function()
    caps(this);
    $type = $(this).attr("id");

    window.timer=setTimeout(function() // setting the delay for each keypress
            ajaxSearchRequest($type); //runs the ajax request

        , 3000);

).keydown(function()clearTimeout(window.timer););

这是ajaxSearchRequest 代码:

function ajaxSearchRequest($type)
                var ajaxRequest2;  // The variable that makes Ajax possible!

                try
                  // Opera 8.0+, Firefox, Safari
                  ajaxRequest2 = new XMLHttpRequest();
                catch (e)
                  // Internet Explorer Browsers
                  try
                     ajaxRequest2 = new ActiveXObject("Msxml2.XMLHTTP");
                  catch (e) 
                     try
                    ajaxRequest2 = new ActiveXObject("Microsoft.XMLHTTP");
                     catch (e)
                    // Something went wrong
                    alert("Browser error!");
                    return false;
                     
                  
                

                ajaxRequest2.onreadystatechange = function()
                  if(ajaxRequest2.readyState == 4)

                        $result = ajaxRequest2.responseText;
                        $('#resultcontainer').html($result);

                    


                var searchterm = document.getElementById($type).value;


                var queryString ="?searchterm=" + searchterm +"&type=" +$type;


                if(searchterm !== "")

                ajaxRequest2.open("GET", "searchrequest.php" + 
                                 queryString, true);
                ajaxRequest2.send(null);
                
        

【问题讨论】:

贴出ajaxSearchRequest的代码 @Imdad 为什么有必要这样做?您已经可以看到每个按键都产生了新的超时,而无需取消之前的按键。 还有其他解决方法。我只能知道我是否知道函数是什么 有没有办法取消 .keydown 上的延迟事件?所以如果没有进一步的 keydown 事件实际上会发生? @krasatos 解决方案是在设置新超时时简单地取消以前的 (.clearTimeout) 超时。那么最后的 keyup 超时不会被取消。 【参考方案1】:

将超时存储在一个变量中,这样您就可以清除最近的超时:

clearTimeout(window.timer);
window.timer=setTimeout(function() // setting the delay for each keypress
                ajaxSearchRequest($type); //runs the ajax request

        , 3000);

【讨论】:

如果您不将该值存储在全局变量中,我会给您 +1... 非常感谢,它成功了,这是最终代码:` $('#lastname').focus(function() $('.terms :input').val("") ; ).keyup(function() caps(this); $type = $(this).attr("id"); window.timer=setTimeout(function() // 设置每个按键的延迟 ajaxSearchRequest( $type); //运行 ajax 请求 , 3000); ).keydown(function()clearTimeout(window.timer););` ffs 这是示例代码。解决方案不需要关闭即可。【参考方案2】:

您正在尝试执行的操作称为去抖动

这是 Ben Alman 的 jquery plugin,可以完成这项工作。

underscore.js 也包含此功能。

真的不需要破解 ajax 请求系统。只需确保在正确的时间调用它即可。

【讨论】:

【参考方案3】:

我喜欢 Molle 的回答,但我会进一步提高性能

var ajaxRequest2;  // The variable that makes Ajax possible!
function getAjaxObject()

                try
                  // Opera 8.0+, Firefox, Safari
                  ajaxRequest2 = new XMLHttpRequest();
                catch (e)
                  // Internet Explorer Browsers
                  try
                     ajaxRequest2 = new ActiveXObject("Msxml2.XMLHTTP");
                  catch (e) 
                     try
                    ajaxRequest2 = new ActiveXObject("Microsoft.XMLHTTP");
                     catch (e)
                    // Something went wrong
                    alert("Browser error!");
                   // return false;
                     
                  
                
  return ajaxRequest2;


 
   getAjaxObject();

    function ajaxSearchRequest($type)



               if(typeof ajaxRequest2 =="undefined" || ajaxRequest2 == false)
                
                  return;
                
               ajaxRequest2.abort();

                ajaxRequest2.onreadystatechange = function()
                  if(ajaxRequest2.readyState == 4)

                        $result = ajaxRequest2.responseText;
                        $('#resultcontainer').html($result);

                    


                var searchterm = document.getElementById($type).value;


                var queryString ="?searchterm=" + searchterm +"&type=" +$type;


                if(searchterm !== "")

                ajaxRequest2.open("GET", "searchrequest.php" + 
                                 queryString, true);
                ajaxRequest2.send(null);
                
        

此更改将中止正在进行的 ajax 请求并发送新请求。

输入-> 等待 4 秒 -> 请求发送 -> 再次输入(未收到响应)-> 等待 4 秒-> 另一个请求触发

【讨论】:

因为答案不好?中止请求无济于事——服务器(通常)继续处理查询。正确的解决方法是不要继续发送请求。 但是,它减少了网络开销。并且解决了如果您打字有点慢时获得多个响应的问题。 不,不发送请求“减少网络开销”。取消 AJAX 请求只会阻止最终答案到达回调。 感谢任何引用来支持您的论点,即“中止不会减少网络开销,只会停止接收到回调的数据” 应该是常识首先发送请求比发送请求但中止请求具有更少的网络开销。

以上是关于尝试向 jQuery AJAX 请求添加延迟的主要内容,如果未能解决你的问题,请参考以下文章

jQuery ajax 请求作为延迟 - 包装失败回调

如何使用js或jQuery向ajax请求添加自定义HTTP标头?

IE8 环境的 JQuery 中的 $.ajax 拒绝访问---解决方案

如何使 JQuery-AJAX 请求同步

jQuery使用ajax跨域请求获取数据

向 Flask 应用程序发出 AJAX 请求