Javascript - 防止函数多次执行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28609994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:15:44  来源:igfitidea点击:

Javascript - prevent function from executing multiple times

javascript

提问by Jorrex

I have a function which is executed on a click (or taphold) because I am working with Cordova.

我有一个在单击(或点击)时执行的函数,因为我正在使用 Cordova。

The problem is that a function calls on the next object from Parse.com which shows its details but, for some reason, it executes the function twice or even 3 times, skipping 1 or 2 objects that have to be shown.

问题是函数调用来自 Parse.com 的下一个对象,该对象显示其详细信息,但由于某种原因,它执行该函数两次甚至 3 次,跳过必须显示的 1 或 2 个对象。

I want to prevent this from happening, so I already used a flag (boolean) to indicate if it was executed by setting it to true. If the flag was false, it can be executed and the flag is set to true. The other problem is that when I call the function one more time, the boolean is still set to true and the function will not be executed.

我想防止这种情况发生,所以我已经使用了一个标志(布尔值)来指示它是否通过将其设置为 true 来执行。如果标志为假,则可以执行并将标志设置为真。另一个问题是,当我再次调用该函数时,布尔值仍然设置为 true 并且该函数不会被执行。

Therefore I cannot initialize the flag to false inside the method, because then it will always be executed. Global variable will be set to true the first time and stay true for the rest of it's "life".

因此我无法在方法内部将标志初始化为 false,因为那样它将始终被执行。全局变量将在第一次设置为 true 并在其“生命”的其余时间保持为 true。

I tried a second method by using a counter and making sure that if the counter reached, let's say 0, it could be executed, but then I have the same problem for setting it back to 0 when it reaches the end .. Let's say the function got executed twice, I could check if the counter reaches 2 (by incrementing it every time) and set it back to 0. Then when the next time it gets executed, it executes 3 times, so when the check happens if the counter reaches 2 .. it get's set back to 0 and the next execution (the 3rd one) will be executed again because the counter is 0 again.

我尝试了第二种方法,通过使用计数器并确保如果计数器达到,假设为 0,它可以被执行,但是当它到达结束时我将它设置回 0 时遇到同样的问题。让我们说函数被执行了两次,我可以检查计数器是否达到 2(通过每次递增)并将其设置回 0。然后在下次执行时,它执行 3 次,因此当计数器达到时进行检查2 .. 它被设置回 0 并且下一次执行(第三次)将再次执行,因为计数器再次为 0。

How do I catch this or prevent this from happening?

我如何抓住这个或防止这种情况发生?

I made a basic Javascript to show you what I mean:

我做了一个基本的 Javascript 来向你展示我的意思:

window.addEventListener("load",setup,false);
var counter = 0;
function setup() {
   for(var i = 0; i < 3; i++) {
       showAlert();
   }
}

function showAlert() {
   if(counter == 0) {
       alert("Executed once");
       counter++;
   } else if(counter > 2) //counter is bigger than 2, so it got executed more than once {
       counter = 0; //reset the counter to 0
   }          
}

The goal is to prevent the function from executing more than once (in this case, the alert may not be shown more than once). It could be executed twice or even three times, or even more. How do I prevent this?

目标是防止函数执行多次(在这种情况下,警报可能不会显示多次)。它可以执行两次甚至三次,甚至更多。我如何防止这种情况?

Thank you! I do know a bit about programming, but this is something I have never encountered so far, so I do not know how I can catch this and make sure it's executed once?

谢谢!我确实对编程有所了解,但这是我迄今为止从未遇到过的事情,所以我不知道如何捕获它并确保它被执行一次?

回答by Lex R

You are experiencing "bounce", a problem caused by one impact registering multiple times in short succession. To get around it, you need to put a very short timeout on your function. (20ms or so) You can either use a third-party library such as LoDash which has many useful utility functions such as _.debouncewhich performs this, or you can do it yourself like this:

您遇到了“反弹”问题,这是由一次冲击在短时间内连续多次注册引起的问题。为了解决这个问题,你需要在你的函数上设置一个非常短的超时时间。(大约 20 毫秒)您可以使用第三方库,例如 LoDash,它具有许多有用的实用功能,例如执行此操作的_.debounce,或者您可以像这样自己做:

var lastClick = 0;
var delay = 20;

function doClick() {
  if (lastClick >= (Date.now() - delay))
    return;
  lastClick = Date.now();

  // do things
  alert("Hello!");
}
<button onclick="doClick()">Push me</button>