Home arrow JavaScript arrow More on Variables, Functions, and Flow Control
JAVASCRIPT

More on Variables, Functions, and Flow Control


In this second part of a two-part series, you'll learn how to delay a function call, handle script errors gracefully, and more. It is excerpted from chapter 4 of the JavaScript & DHTML Cookbook, Second Edition, written by Danny Goodman (O'Reilly, 2008; ISBN: 0596514085). Copyright 2008 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Author Info:
By: O'Reilly Media
Rating: 5 stars5 stars5 stars5 stars5 stars / 4
December 14, 2009
TABLE OF CONTENTS:
  1. · More on Variables, Functions, and Flow Control
  2. · 4.6 Branching Execution Based on Conditions
  3. · 4.7 Handling Script Errors Gracefully
  4. · 4.8 Improving Script Performance

print this article
SEARCH DEVARTICLES

More on Variables, Functions, and Flow Control
(Page 1 of 4 )

4.5 Delaying a Function Call

Problem

You want a function to run at a specified time in the near future.

Solution

Use the window.setTimeout() method to invoke a function one time after a delay of a number of milliseconds. You essentially set a timer to trigger a function of your choice. In its most common form, the function is referenced as a string, complete with parentheses, as in the following example:

  var timeoutID = setTimeout("myFunc()", 5000);

The method returns an ID for the time-out operation and should be preserved in a global variable or property of a global object. If, at any time before the delayed function fires, you wish to abort the timer, invoke the clearTimeout() method with the time-out ID as the parameter:

  clearTimeout(timeoutID);

Once the timer is set, other script processing may proceed as usual, so it is often a good idea to place the setTimeout() call as the final statement of a function.

Discussion

It's important to understand what the setTimeout() method doesn't do: it does not halt all processing in the manner of a delay that suspends activity until a certain time. Instead, it simply sets an internal countdown timer that executes the named function when the timer reaches zero. For example, if you are creating a slide show that should advance to another page after 15 seconds of inactivity from the user, you would initially set the timer via the load event handler for the page and the resetTimer() function:

  var timeoutID;
  function goNextPage() {
     
location.href = "slide3.html";
  }
  function resetTimer() {
     
clearTimeout(timeoutID);
      timeoutID = setTimeout("goNextPage()", 15000);
  }

You would also set an event handler for, say, the mousemove event so that each time the user activates the mouse, the autotimer resets to 15 seconds:

  window.onmousemove = resetTimer;

The resetTimer() function automatically cancels the previously set time-out before it triggers the goNextPage() function, and then it starts a new 15-second timer.

If the function you are invoking via the delay requires parameters, you can assemble a string with the values, even if those values are in the form of variables within the function. But--and this is important--the variable values cannot be object references. Parameters must be in a form that will survive the conversion to the string needed for the first argument of the
setTimeout() method. Recipe 8.4 demonstrates how you can convey names of DOM form-related objects as ways of passing an object reference. The tricky part is in keeping the quotes in order:

  function isEMailAddr(elem) {
     
var str = elem.value;
     
var re = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
     
if (!str.match(re)) {
         
alert("Verify the e-mail address format.");
         
setTimeout("focusElement('" + elem.form.name + "', '" + elem.name + "')", 0);
         
return false;
     
} else {
          return true;
      }
  }

In this example, the focusElement() function requires two parameters that are used to devise a valid reference to both a form object and a text input object. Both parameters of the focusElement() function are strings. Because the first argument of setTimeout() is, itself, a string, you have to force the "stringness" of the parameters to focusElement() by way of single quotes placed within the extended string concatenation sequence. (The zero milliseconds shown in the example is not a mistake for this application. Learn why in the Discussion for Recipe 8.4.)

Conveniently, setTimeout() also accepts a function reference as its first parameter, thus opening up the possibility of using an anonymous function in that spot. Staying with the previous example, we can invoke multiple method calls within a single anonymous function, as in the following:

  setTimeout(function() {elem.focus(); elem.select();}, 0);

This approach circumvents all the string machinations of the other format.

If you are looking for a true delay between the execution of statements within a function or sections of a function, JavaScript has nothing comparable to commands available in some other programming languages. But you can accomplish the same result by dividing the original function into multiple functions--one function for each section that is to run after a delay. Link the end of one function to the next by ending each function with setTimeout(), which invokes the next function in sequence after the desired amount of time:

  function mainFunc() {
     
// initial statements here
     
setTimeout("funcPart2()", 10000);
 
}
 
function funcPart2() {
     
// initial statements here
     
setTimeout("finishFunc()", 5000);
  }
  function finishFunc() {
     
// final batch of statements here
  }

The related functions don't have to be located adjacent to each other in the source code. If all related functions need to operate on the same set of values, you can cascade the value as parameters (provided the parameters can be represented as nonobject values), or you can preserve them as global variables. If the values are related, it may be a good reason to define a custom object with values assigned to labeled properties of that object to make it easier to see at a glance what each function segment is doing with or to the values.

Another JavaScript method, setInterval(), operates much like setTimeout(), but repeatedly invokes the target function until told to stop (via the clearInterval() method). The second parameter (an integer in milliseconds) controls the amount of time between calls to the target function.

See Also

Recipe 8.4 for using setTimeout() to keep script execution synchronized; Recipe 12.6 for an example of using a self-contained counter variable in a repeatedly invoked function to execute itself a fixed number of times; Recipes 13.9 and 13.10 for applications of setInterval() in animation.


blog comments powered by Disqus
JAVASCRIPT ARTICLES

- Project Nashorn to Make Java, JavaScript Wor...
- JavaScript Virus Attacks Tumblr Blogs
- Google Releases Stable Dart Version, JavaScr...
- Khan Academy Unveils New JavaScript Learning...
- Accessing Nitro? There`s an App for That
- JQuery 2.0 Leaving Older IE Versions Behind
- Fastest JavaScript Engine Might Surprise You
- Microsoft Adjusting Chakra for IE 10
- Brendan Eich: We Don`t Need Google Native Cl...
- An Overview of JavaScript Statements
- An Overview of JavaScript Operators
- Overview of JavaScript Variables
- More of the Top jQuery Social Plugins
- The Top jQuery Social Plugins
- More of the Top jQuery Slider Plugins

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials