如何防止在短时间内触发多个 AJAX 请求?

huangapple go评论120阅读模式
英文:

How to prevent input event from firing multiple AJAX requests within a short time?

问题

我在一个JavaScript事件中遇到了问题,当快速触发事件时,会发送多次AJAX请求。假设我有一个输入字段,它在“change”事件上触发一个AJAX请求。然而,如果我在输入字段中快速输入单词“phone”,AJAX请求将被发送五次而不是一次。我想引入一个延迟,确保在该延迟内触发新的change事件时,前一个进程被取消,只发送最新的请求。

这是我一直在努力的代码片段:

$(document).on("input", "#product_search", function (e) {
let debounceTimer;
clearTimeout(debounceTimer);
debounceTimer = setTimeout(function () {
let inputValue = e.target.value;
$.ajax({
url: "pages/get_all_products.php",
method: "POST",
data: {
search: inputValue,
},
beforeSend: function () {
console.log("sending");
},
success: function (response) {
// 处理响应
},
error: function () {
console.log("error");
},
complete: function () {
console.log("completed");
},
});
}, 100);
});


不幸的是,这段代码并没有解决问题,因为在快速输入时,AJAX请求仍然会被触发多次。我将非常感激任何关于如何为这种情况实现正确的防抖功能的指导。我希望如果我输入得足够快,它只发送一个请求。

我已经尝试使用debounceTimer变量来清除定时器并重置定时器,但似乎没有按预期工作。

请问是否有人能帮我理解如何正确地对事件进行防抖,以便即使在短时间内多次触发事件,也只发送最新的AJAX请求?
英文:

I'm facing an issue with a JavaScript event where an AJAX request is sent multiple times when the event is triggered rapidly. Let's say I have an input field that triggers an AJAX request on the "change" event. However, if I quickly type the word "phone" in the input field, the AJAX request is sent five times instead of just once. I want to introduce a delay and ensure that if a new change event is fired within that delay, the previous process is canceled and only the latest request is sent.

Here's the code snippet I've been working on:

$(document).on("input", "#product_search", function (e) {
    let debounceTimer;
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(function () {
        let inputValue = e.target.value;
        $.ajax({
            url: "pages/get_all_products.php",
            method: "POST",
            data: {
                search: inputValue,
            },
            beforeSend: function () {
                console.log("sending");
            },
            success: function (response) {
                // Process the response
            },
            error: function () {
                console.log("error");
            },
            complete: function () {
                console.log("completed");
            },
        });
    }, 100);
});

Unfortunately, this code doesn't solve the issue, as the AJAX request is still being triggered multiple times when typing quickly. I would greatly appreciate any guidance on how to implement a proper debounce functionality for this scenario. I expect it to send single request if I type fast enough.

I have already attempted to use the debounceTimer variable to clearTimeout() and reset the timer, but it doesn't seem to be working as expected.

Could someone please help me understand how to correctly debounce the event, so that only the latest AJAX request is sent even if the event is triggered multiple times within a short time frame?

答案1

得分: 4

It seems the variable declaration let debounceTimer should be outside of the oninput handler.

Otherwise, the variable is declared each time the event fires, it does not persist outside of the handler function, and its associated timer cannot be cleared by subsequent events. This is because a variable declared by let is "limited to the scope of a block statement, or expression on which it is used" (let @ MDN).

You may also want to increase the debounce time, depending on how fast you expect users to type.

英文:

It seems the variable declaration let debounceTimer should be outside of the oninput handler.

Otherwise, the variable is declared each time the event fires, it does not persist outside of the handler function, and its associated timer cannot be cleared by subsequent events. This is because a variable declared by let is "limited to the scope of a block statement, or expression on which it is used" (let @ MDN).

You may also want to increase the debounce time, depending on how fast you expect users to type.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let debounceTimer;
$(document).on(&quot;input&quot;, &quot;#product_search&quot;, function(e) {
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(function() {
    console.log(&#39;Go!&#39;);
  }, 300);
});

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;input id=&quot;product_search&quot;&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月29日 10:25:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76577711.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定