How do you handle multiple instances of setTimeout()?

前端 未结 9 2038
鱼传尺愫
鱼传尺愫 2020-12-01 05:18

What is the most recommended/best way to stop multiple instances of a setTimeout function from being created (in javascript)?

An example (psuedo code):



        
相关标签:
9条回答
  • 2020-12-01 06:01

    I'm using this to force a garbage collection on all obsolete timeout references which really un-lagged my script preformance:

    var TopObjList = new Array();
    function ColorCycle( theId, theIndex, RefPoint ) {
        ...
        ...
        ...
        TopObjList.push(setTimeout( function() { ColorCycle( theId, theIndex ,CCr ); },CC_speed));
        TO_l = TopObjList.length;
        if (TO_l > 8888) {
            for (CCl=4777; CCl<TO_l; CCl++) {
                clearTimeout(TopObjList.shift());
                }
            }
        }
    

    My original sloppy code was generating a massive array 100,000+ deep over a very short time but this really did the trick!

    0 讨论(0)
  • 2020-12-01 06:04

    when you call settimeout, it returns you a variable "handle" (a number, I think)

    if you call settimeout a second time, you should first

    clearTimeout( handle )
    

    then:

    handle = setTimeout( ... )
    

    to help automate this, you might use a wrapper that associates timeout calls with a string (i.e. the div's id, or anything you want), so that if there's a previous settimeout with the same "string", it clears it for you automatically before setting it again,

    You would use an array (i.e. dictionary/hashmap) to associate strings with handles.

    var timeout_handles = []    
    function set_time_out( id, code, time ) /// wrapper
    {
        if( id in timeout_handles )
        {
            clearTimeout( timeout_handles[id] )
        }
    
        timeout_handles[id] = setTimeout( code, time )
    }
    

    There are of course other ways to do this ..

    0 讨论(0)
  • 2020-12-01 06:04

    You can avoid a global or lesser variable by using a property within the function. This works well if the function is only used for this specific context.

    function set_time_out( id, code, time ) /// wrapper
    {
      if(typeof this.timeout_handles == 'undefined') this.timeout_handles = [];
    
            if( id in this.timeout_handles )
            {
                    clearTimeout( this.timeout_handles[id] )
            }
    
            this.timeout_handles[id] = setTimeout( code, time )
    }
    
    0 讨论(0)
  • 2020-12-01 06:05

    You can set a global flag somewhere (like var mouseMoveActive = false;) that tells you whether you are already in a call and if so not start the next one. You set the flag just before you enter the setTimeout call, after checking whether it's already set. Then at the end of the routine called in setTimeout() you can reset the flag.

    0 讨论(0)
  • 2020-12-01 06:12

    I haven't tested any of this, and just cut this up in the editor here. Might work, might not, hopefully will be food for thought though.

    var Timeout = { 
       _timeouts: {}, 
       set: function(name, func, time){ 
         this.clear(name); 
         this._timeouts[name] = {pending: true, func: func}; 
         var tobj = this._timeouts[name];
         tobj.timeout = setTimeout(function()
         { 
    /* setTimeout normally passes an accuracy report on some browsers, this just forwards that. */
           tobj.func.call(arguments); 
           tobj.pending = false;
         }, time); 
       },
       hasRun: function(name)
       { 
           if( this._timeouts[name] ) 
           {
              return !this._timeouts[name].pending; 
           }
           return -1; /* Whut? */ 
       },
       runNow: function(name)
       {
          if( this._timeouts[name] && this.hasRun(name)===false )
          {
             this._timeouts[name].func(-1); /* fake time. *shrug* */
             this.clear(name);
          }
       } 
       clear: function(name)
       {
         if( this._timeouts[name] && this._timeouts[name].pending ) 
         {
           clearTimeout(this._timeouts[name].timeout); 
           this._timeouts[name].pending = false; 
         }
       }
    };
    
    Timeout.set("doom1", function(){ 
      if(  Timeout.hasRun("doom2") === true )
      {
         alert("OMG, it has teh run");  
      }
    }, 2000 ); 
    Timeout.set("doom2", function(){ 
       /* NooP! */
    }, 1000 ); 
    

    Successive calls with the same identifier will cancel the previous call.

    0 讨论(0)
  • 2020-12-01 06:14

    you can always overwrite the buttons onclick to return false. example:

    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="UTF-8">
    <head>
        <title>Javascript example</title>
        <script type="text/javascript">         
            var count = 0;
            function annoy() {
                document.getElementById('testa').onclick = function() { return false; };
    
                setTimeout(function() {
                    alert('isn\'t this annoying? ' + count++);
                    document.getElementById('testa').onclick = window.annoy;
                }, 1000);
    
            }
        </script>
    </head>
    <body>
        <h2>Javascript example</h2>
        <a href="#" onClick="annoy()" id="testa">Should Only Fire Once</a><br />
    </body>
    </html>
    
    0 讨论(0)
提交回复
热议问题