<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="/lib/xsl/devedge-1.00/article_en.xsl"?>
<nde:article 
  url="/toolbox/examples/2003/CCallWrapper/" 
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:nde="http://devedge.netscape.com/2002/de" 
  xmlns:ent="http://devedge.netscape.com/2003/ent"
  xml:lang="en">

  <nde:header>

    <nde:title>
      A JavaScript Wrapper for Making Asynchronous Function
      and Object Method Calls 
    </nde:title>

    <nde:category>
      Example
    </nde:category>

    <nde:pubdate year="2003" month="06" day="06"/>
    <nde:moddate year="2003" month="07" day="08"/>

    <nde:summary>
      The normal means of calling functions asynchronously
      in JavaScript can be painful and downright impossible if you want to 
      call Object methods asynchronously. See how CCallWrapper simplifies 
      making asynchronous function and Object method calls in 
      Netscape 4.x, Netscape 6, Netscape 7, Mozilla, 
      Gecko-based browsers, Internet Explorer and Opera 7.
    </nde:summary>
    
    <nde:channels>
      <nde:channel id="dom"/>
      <nde:channel id="examples"/>
    </nde:channels>
    
    <nde:keywords>
      Netscape, Netscape 7, Mozilla, Gecko, Opera, Internet Explorer, Asynchronous, setTimeout, setInterval, JavaScript
    </nde:keywords>
    
    <nde:authlist>
      <nde:author>
        <nde:authname>Bob Clary</nde:authname>
        <nde:authtitle>Evangelist</nde:authtitle>
        <nde:authaffil>Netscape Communications</nde:authaffil>
      </nde:author>
    </nde:authlist>

  </nde:header>

  <nde:head>
  </nde:head>

  <nde:content>

    <h2 name="introduction">Introduction</h2>

    <p>
      Performing asynchronous calls is important in Graphical
      User Interface programming in general and is even more
      so when developing complex web applications which perform
      lengthy operations. Unfortunately, JavaScript<ent:trade/>
      can make the task of performing asynchronous calls 
      complicated.
    </p>
    <p>
      The normal means of calling functions asynchronously
      in JavaScript can be painful and downright impossible if you want to 
      call Object methods asynchronously. See how CCallWrapper simplifies 
      making asynchronous function and Object method calls in 
      Netscape 4.x, Netscape 6, Netscape 7, Mozilla, 
      Gecko-based browsers, Internet Explorer and Opera 7.
    </p>

    <p>
      <code>CCallWrapper</code> provides an easy to use, cross-browser
      means of asynchronously calling functions and Object methods which
      works in Netscape 4.x, Netscape 6, Netscape 7, Mozilla, all Gecko-based browsers, Internet Explorer
      and Opera<ent:trade/>.
    </p>

    <h3 name="example1">Example 1</h3>

    <p>
      Performing asynchronous function calls in JavaScript
      using arguments normally involves constructing
      the expression argument to <code><a href="/library/manuals/2000/javascript/1.3/reference/window.html#1203758">setTimeout</a></code> 
      or <code><a href="/library/manuals/2000/javascript/1.3/reference/window.html#1203669">setInterval</a></code> manually.
    </p>

    <pre><![CDATA[// Say Hi after a 1 second delay
var hi = 'Howdie Pardner!';
      
function sayHi(message)
{
  alert(message);
}

function doExample1()
{
  setTimeout('sayHi("' + hi + '")', 1000);
}]]></pre>

    <script type="text/javascript"><![CDATA[
var hi = 'Howdie Pardner!';
      
function sayHi(message)
{
  alert(message);
}

function doExample1()
{
  setTimeout('sayHi("' + hi + '")', 1000);
}]]></script>
    <form method="get" action="">
      <input type="button" onclick="doExample1()" value="Run Example 1" />
    </form>

    <p>
      This example works cross browser in Netscape 7, Mozilla,
      other Gecko-based browsers, Internet Explorer, Opera, etc.
    </p>

    <h3 name="example2">Example 2</h3>

    <p>
      Netscape Navigator 4.x and Gecko-based browsers 
      provide an extension of <code>setTimeout</code> and 
      <code>setInterval</code> where a reference to the function
      to be called and its arguments can be specified.
    </p>

    <pre><![CDATA[// Say Hi after a 1 second delay
var hi = 'Howdie Pardner!';
      
function sayHi(message)
{
  alert(message);
}

function doExample2()
{
  setTimeout(sayHi, 1000, hi);
}]]></pre>

    <script type="text/javascript"><![CDATA[
var hi = 'Howdie Pardner!';
      
function sayHi(message)
{
  alert(message);
}

function doExample2()
{
  setTimeout(sayHi, 1000, hi);
}]]></script>
    <form method="get" action="">
      <input type="button" onclick="doExample2()" value="Run Example 2" />
    </form>

    <p>
      This example works in Netscape 7, Mozilla,
      other Gecko-based browsers but not in Internet Explorer or
      Opera.
    </p>

    <h3 name="example3">Example 3</h3>

    <p>
      Unfortunately, the extension to <code>setTimeout</code> and
      <code>setInterval</code> does not work when it 
      comes to making asynchronous calls on <em>Object methods</em>.
    </p>

    <pre><![CDATA[
function CTalker(name)
{
  this.name = name;
}

CTalker.prototype.talk =
function(message)
{
  alert(this.name + ' says ' + message);
};

function doExample3()
{
  var hi = 'Howdie Pardner!';
  var talker = new CTalker('He who speaks loudly, saying nothing');
  setTimeout(talker.talk, 1000, hi);
}]]></pre>

    <script type="text/javascript"><![CDATA[
function CTalker(name)
{
  this.name = name;
}

CTalker.prototype.talk =
function(message)
{
  alert(this.name + ' says ' + message);
};

function doExample3()
{
  var hi = 'Howdie Pardner!';
  var talker = new CTalker('He who speaks loudly, saying nothing');
  setTimeout(talker.talk, 1000, hi);
}]]></script>
    <form  method="get" action="">
      <input type="button" onclick="doExample3()" value="Run Example 3" />
    </form>

    <p>
      In Netscape 7, Mozilla and other Gecko-based browsers, this 
      example calls the <code>CTalker.talk</code> method
      but does not reference the instance used in the
      call to <code>setTimeout</code>.
    </p>

    <p>
      While the approach used in <a href="#example1">Example 1</a>
      works cross browser its limitations can make life difficult
      for Web developers. <a href="#example2">Example 2</a> is
      promising but the lack of cross browsers support and
      the problem of calling methods as illustrated in 
      <a href="#example3">Example 3</a> prevent this extension
      to <code>setTimeout</code> and <code>setInterval</code>
      from being more useful.
    </p>
      
    <p>
      The JavaScript Object CCallWrapper is designed to work around 
      these problems and make the use of asynchronous calls almost
      as simple as normal calls.
    </p>

    <h2 name="script">Script</h2>

    <p>
      <code><a href="CCallWrapper.js">CCallWrapper.js</a></code> 
      implements
      a JavaScript Object <code>CCallWrapper</code> which is used to 
      manage making asynchronous function and method calls.
    </p>

    <dl>
      <dt>Constructor</dt>
      <dd>
        <dl>
          <dt>CCallWrapper(Object aObjectReference, 
            Number aDelay,
            String aMethodName,
            aArgument0, aArgument1, ..., aArgument9)</dt>
          <dd>
            <p>
              Constructs an instance of a CCallWrapper object 
              which can be used to execute the <code>aMethodName</code>
              method/function in the scope of the <code>aObjectReference</code>
              using up to 10 optional arguments after a delay
              of <code>aDelay</code> milliseconds.
            </p>
          </dd>
        </dl>
      </dd>
      <dt>Class Properties</dt>
      <dd>
        <dl>
          <dt>Number CCallWrapper.mCounter</dt>
          <dd>
            <p>
              <code>mCounter</code> is used to track the number of
              instances of <code>CCallWrapper</code> which have been
              created and to create unique <em>names</em> for them.
            </p>
          </dd>
          <dt>Object CCallWrapper.mPendingCalls</dt>
          <dd>
            <p>
              <code>mPendingCalls</code> is a <em>Hash</em> which
              contains instances of <code>CCallWrapper</code> waiting
              to be executed. 
            </p>
          </dd>
        </dl>
      </dd>
      <dt>Class Methods</dt>
      <dd>
        <dl>
          <dt>CCallWrapper.asyncExecute(CCallWrapper callwrapper)</dt>
          <dd>
            <p>
              <code>asyncExecute</code> is used to asynchronously
              execute the specified <code>callwrapper</code>.
            </p>
          </dd>
        </dl>
      </dd>
      <dt>Properties</dt>
      <dd>
        <dl>
          <dt>String mId</dt>
          <dd>
            <p>
              <code>mId</code> is used to obtain a reference to the
              instance of <code>CCallWrapper</code> maintained in
              the class property <code>mPendingCalls</code>.
            </p>
          </dd>
          <dt>Object mObjectReference</dt>
          <dd>
            <p>
              <code>mObjectReference</code> is the <em>scope</em>
              object used to execute the specified function or method.
              For example, when the <code>CCallWrapper</code> is executed,
              mObjectReference[mMethodName](....) will be called.
            </p>
          </dd>
          <dt>Object aArgument0, ..., aArgument9</dt>
          <dd>
            <p>
              aArgument0, ... ,aArgument9 are the argument values to 
              be passed to the function/method when it is called.
            </p>
          </dd>
          <dt>Number mDelay</dt>
          <dd>
            <p>
              <code>mDelay</code> is the time interval in milliseconds
              before the <code>callwrapper</code> is executed.
            </p>
          </dd>
          <dt>Number mTimerId</dt>
          <dd>
            <p>
              <code>mTimerId</code> is the return value of the
              <code>setTimeout</code> function used to implement
              asynchronous calls. It is used by the <code>cancel</code>
              method.
            </p>
          </dd>
        </dl>
      </dd>
      <dt>Methods</dt>
      <dd>
        <dl>
          <dt>execute()</dt>
          <dd>
            <p>
              <code>execute()</code> will invoke the wrapped object
              as <code>this.mObjectReference[this.mMethodName](this.mArgument0, ... , this.mArgument9)</code>.
            </p>
          </dd>
          <dt>cancel()</dt>
          <dd>
            <p>
              <code>cancel()</code> will cancel the pending 
              asynchronous execution of the <code>CCallWrapper</code>.
            </p>
          </dd>
        </dl>
      </dd>
    </dl>

    <h2 name="example4">Example 4</h2>
    <p>
      Using <code>CCallWrapper</code> we can revisit <a href="#example3">Example 3</a>.
    </p>

    <script type="text/javascript" src="CCallWrapper.js"></script>
    <pre><![CDATA[
function doExample4()
{
  var hi = 'Howdie Pardner!';
  var talker = new CTalker('He who speaks loudly, saying nothing');
  var callwrapper = new CCallWrapper(talker, 1000, 'talk', hi);
  CCallWrapper.asyncExecute(callwrapper);
}]]></pre>

    <script type="text/javascript"><![CDATA[
function doExample4()
{
  var hi = 'Howdie Pardner!';
  var talker = new CTalker('He who speaks loudly, saying nothing');
  var callwrapper = new CCallWrapper(talker, 1000, 'talk', hi);
  CCallWrapper.asyncExecute(callwrapper);
}]]></script>
    <form method="get" action="">
      <input type="button" onclick="doExample4()" value="Run Example 4" />
    </form>

    <p>
      This example works in Netscape 4.x, Netscape 6.x, Netscape 7.x,
      Mozilla, all Gecko-based browsers, Internet Explorer and 
      Opera 7.
      </p>

      <h2 name="changelog">Change Log</h2>

        <dl>
          <dt>2003-07-08</dt>
          <dd>
            <p>
              Added <code>mTimerId</code> property and 
              <code>cancel</code> method.
            </p>
          </dd>
        </dl>

  </nde:content>

  <nde:related area="nde">
    <nde:item url="/library/manuals/2000/javascript/1.3/reference/window.html#1203758">setTimeout</nde:item>
    <nde:item url="/library/manuals/2000/javascript/1.3/reference/window.html#1203669">setInterval</nde:item>
    <nde:item url="/central/">DOM Central</nde:item>
    <nde:item url="/toolbox/examples/">Examples</nde:item>
  </nde:related>
  
</nde:article>
