避免JavaScript中的竞争条件(使用settimeout时)

时间:2018-06-27 04:07:37

标签: javascript

我有一个JS函数,当单击按钮时会调用该函数。超时后也会调用同一函数(使用setTimeout)。当有人单击按钮并同时调用setTimout时,如何避免出现竞争状况?

4 个答案:

答案 0 :(得分:1)

您似乎在想这两个函数可能会在完全相同的时间被调用,因此会导致竞争。但是Javascript使用单线程的Event Loop,这意味着这些函数将被推送到一堆函数中,无论调用它们时,它们都会被一一执行。

答案 1 :(得分:1)

单击按钮时调用的JS函数是回调函数。超时后执行的JS函数也是回调函数。在您的情况下,这两个恰好是相同的。它们都将放置在任务队列中,当清除调用栈时,JS事件循环会将它们从其中移至调用栈。将它们中的每个放置在调用堆栈中后,它​​们将被执行。因此,将第一个放入队列后,它便会执行。然后,调用堆栈将清除。然后,JS事件循环将第二个事件从任务队列中拉出并放置在调用堆栈中。

JS运行时一次只能做一件事。因此没有比赛条件。

此视频https://www.youtube.com/watch?v=8aGhZQkoFbQ可以详细介绍

答案 2 :(得分:0)

您可以使用“ setInterval”代替“ setTimeout”。因此,在按钮中单击可以清除间隔并再次设置间隔。您可以参考下面的代码。

<!DOCTYPE html>
 <html>
  <head>
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
   <script>
     var myVar;
     $(document).ready(function(){
       myVar = setInterval(myFunctionInterval, 5000);
     });

     function myFunctionInterval() {
       alert("Hello (From Interval) !");
     }

     function clearLoop() {
       clearInterval(myVar);
       myVar = setInterval(myFunction, 5000);
     }

     function myFunction() {
       alert("Hello (From Button)!");
     }
    </script>
   </head>
   <body>

      <button onclick="clearLoop()">Click me</button>

   </body>
  </html>

答案 3 :(得分:-1)

按下按钮时清除setTimeout回调,例如:

<button onClick='onClick()'/>

var onClick = () => {clearTimeout(yourTimer); yourFunc()}