Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5
  1. #1
    glz
    glz is offline
    New Coder
    Join Date
    Apr 2007
    Posts
    57
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Exclamation using setInterval in loops

    Hi i'm scratching my head over achieving similar results with setInterval() function, and how I can keep it from looping infinitely.

    I want to do something like this:
    Code:
    var i = 0;
    var endTime = now + ((1000*60)*2); // 2 minutes after now
    while (now <=endTime) {
    	i = i + 1;
    	now = new Date().getTime();
    }
    document.write("total iterations: " + i);
    however you can't do this because of lag issues, so i'll settle for using setinterval on its smallest interval of a millisecond, here is my attempt to translate the above to a setinterval solution:
    Code:
    var endTime = now + ((1000*60)*2); // 2 minutes after now
    var intervalID = setInterval(loopFunc(endTime),1);
    function loopFunc(endTime,intervalID) {
    	if (new Date().getTime() <= endTime) {
    		i = i + 1;
    	} else {
    		clearInterval(intervalID);
    	}
    }
    as you can see I have prolbems figuring out how to stop the interval from continuing to iterate, and passing the interval id, I'm clueless
    Also I'm clueless on echoing the total iterations via this method.

    Help me out!
    Thanks

  • #2
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    Code:
    setInterval(loopFunc(endTime), 1);
    loopFunc(endTime) returns the value undefined, not a function. But setInterval() expects a function as an argument.

    Code:
    var i = 0;
    var now = new Date().getTime();
    var endTime = now + ((1000*10)*1); // 10secs after now
    
    var intervalID = setInterval(function() {
      loopFunc(endTime, intervalID);
      }, 1);
    
    function loopFunc(endTime, intervalID) {
      if (new Date().getTime() <= endTime) {
        i = i + 1;
      }
      else {
        clearInterval(intervalID);
        document.body.appendChild(document.createTextNode("total iterations: " + i));
      }
    }
    Edit:
    Note: this version of the code is a little vulnerable. It really should use a closure to do the job. If anything, my second post has robust code. In case you were wondering, it uses a closure, but for a different reason. The function that is assigned to f in that code creates a closure. If you don't understand what one is, please ask me. It's an important concept for more advanced Javascript.
    Last edited by Trinithis; 12-15-2007 at 07:23 AM. Reason: a little explanation
    Trinithis

  • #3
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    Without creating any globals, it might look like . . .

    Code:
    ({
      count: 0,
      callback: function() {
        ++this.count;
        if(new Date().getTime() < this.end)
          return;
        document.body.appendChild(document.createTextNode("Total iterations: " + this.count));
        clearInterval(this.interval);
      },
      init: function() {
        var t = this, f = function() {
          t.callback();
        };
        this.end = new Date().getTime() + 1000 * 60 * 2;
        this.interval = setInterval(f, 1);
      }
    }).init();
    Trinithis

  • #4
    glz
    glz is offline
    New Coder
    Join Date
    Apr 2007
    Posts
    57
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Code:
    var intervalID = setInterval(function() { loopFunc(endTime, intervalID);}, 0);

    I don't understand this line of code, what do you say function() etc... can't you just call the function like:

    setInterval("loopFunc(endTime,intervalID)",0);

    or

    setInterval("loopFunc(+ endTime +, + intervalID +)",0);

    i've seen this syntax in some online examples/tuts
    can you offer explanation on yours, or offer links to documentation where it explains it?
    -thank you

  • #5
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    In Javascript, you can pass functions around just like any other variable (they are objects).

    Code:
    function reallyLongName(x) {
      alert("Number is " + x);
    }
    
    var short = reallyLongName;
    short(1); // "Number is 1"
    
    function otherFunc(f) {
      f(2);
    }
    otherFunc(reallyLongName); // "Number is 2"
    otherFunc(short); // "Number is 2"
    Just like otherFunc, setInterval takes a function as its first argument. Internally, it might look like this (vastly simplified) psuedo-code:

    Code:
    setInterval(func, interval) {
      if(time &#37; interval == 0)
        func();
      setInterval(func, interval);
    }
    Note that when setInterval calls func, it uses a set of parenthesis with nothing in them. This means that the function's arguments (if any) have the value undefined. The question is how to send setInterval a function and have it execute that function with arguments.

    Let's say you want to have setInterval alert "hello" every 30 seconds. Well, what if you did the following:

    Code:
    function alertHello() {
      alert("hello");
    }
    
    setInterval(alertHello, 30000);
    It works!

    The problem with this is that you can end up littering your code with a bunch of alertXXXX function declarations if you want to have a series of alerts with different texts.

    There turns out to be another way to create a function: the function expression.

    Code:
    // function declaration
    // function is created at "compile" time
    function x() {...}
    
    // function expression
    // function is created at "run" time
    var x = function() {...};
    
    // the function() {...} part
    // is called a function literal. It is also
    // called an anonymous function.
    Looking at the function expression version of the code, let's understand how it works. The computer creates a variable called x. Then it asks what x is equal to. It looks to the right of the assignment operator and says "Hey, there's a function literal. I need to create a function on the heap." The computer reads the contents of the function and evaluates it and stores the result on the heap. It is put on the heap because functions are instances of the Function class, with is in turn extended from the umbrella Object class. And hopefully you know that objects are created on the heap. Other variables are created on the stack.

    In any case, it's in the heap. Meanwhile, x is yelling at the computer "I still don't know what I'm equal to!" Your computer obliges x and sends it a reference to your new function.

    So what about the following?

    Code:
    setInterval(
      function () {
        alert("hello");
      }, 30000);
    Let's look again at my setInterval psuedo-code. In specific, look at setInterval's func argument. Just like the complaining x, it asks the computer to assign it a value. The computer looks at the arguments and sees a function literal. It turns it into computer code, tosses the resulting function on the heap, and sends a reference to func.

    -----------
    As a side note, I was mistaken when I sent setInterval a zero for its interval time. Doesn't work properly in IE. Also, sending strings to setTimeout/setInterval is comparatively slow.
    Last edited by Trinithis; 12-15-2007 at 08:01 AM.
    Trinithis


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •