Wrox Programmer Forums
Go Back   Wrox Programmer Forums > Web Programming > JavaScript > BOOK: Professional Ajax 2nd Edition ISBN: 978-0-470-10949-6
| Search | Today's Posts | Mark Forums Read
BOOK: Professional Ajax 2nd Edition ISBN: 978-0-470-10949-6
This is the forum to discuss the Wrox book Professional Ajax, 2nd Edition by Nicholas C. Zakas, Jeremy McPeak, Joe Fawcett; ISBN: 9780470109496
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Professional Ajax 2nd Edition ISBN: 978-0-470-10949-6 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old March 3rd, 2009, 08:54 AM
Registered User
 
Join Date: Mar 2009
Posts: 3
Thanks: 1
Thanked 0 Times in 0 Posts
Default Request Management (Ch5) Inquiry about checkActiveRequests

Hi I have a question regarding the anonymous function in the end of the _checkActiveRequests method. Specifically, I fail to understand why there is a need to define and return yet another anonymous function inside the anonymous function. The original code is as follows:

Code:
if ( fnCallback != null ) {
    setTimeout( (function (fnCallback, oRequest, oTransport) {
        return function () {
            fnCallback.call(oRequest.scope||window, {
                status : oTransport.status,
                data : oTransport.responseText,
                request : oRequest });
        }
    })(fnCallback, oRequest, oTransport), 1);
}
Why can't this code be like follows?

Code:
if ( fnCallback != null ) {
    setTimeout( (function (fnCallback, oRequest, oTransport) {
            fnCallback.call(oRequest.scope||window, {
                status : oTransport.status,
                data : oTransport.responseText,
                request : oRequest });
    })(fnCallback, oRequest, oTransport), 1);
}
or simply

Code:
if ( fnCallback != null ) {
    setTimeout( 
        fnCallback.call(oRequest.scope||window, {
                status : oTransport.status,
                data : oTransport.responseText,
                request : oRequest } ), 1);
}
 
Old March 7th, 2009, 05:54 PM
nzakas's Avatar
Wrox Author
 
Join Date: Dec 2004
Location: Peabody, MA, USA.
Posts: 217
Thanks: 0
Thanked 5 Times in 5 Posts
Default

Hi,

The reason this is necessary is because the entire code block that you pasted is contained within a "for" loop. At the top of the loop, you'll see this:

Code:
oRequest = this._active[i];
oTransport = oRequest.transport;
Without the extra anonymous function, the variables oRequest and oTransport will be bound to their last value in the loop. You can verify this yourself with a simple example:

Code:
var funcs = [];
for (var i=0; i < 10; i++){
    funcs[i] = function(){ return i; };
}

alert(funcs[0]());  //10
All of the functions in this code reference "i"...but they all reference the exact same "i" so all functions in the array return 10 (the last value of "i"). You fix this by wrapping the inner part in an anonymous function:

Code:
var funcs = [];
for (var i=0; i < 10; i++){
    funcs[i] = function(value){ 
        return function(){
            return value;
        }
    }(i);
}

alert(funcs[0]());  //0
By wrapping the creating function in an anonymous function and then passing in the value of "i", it creates a copy of the value that can then be safely returned. This is important in the request manager to be sure you're always referring to the correct request.

Hope this helps clear things up.
__________________
Nicholas C. Zakas
Author, Professional JavaScript for Web Developers (ISBN 0764579088)
http://www.nczonline.net/
 
Old March 8th, 2009, 12:45 AM
Registered User
 
Join Date: Mar 2009
Posts: 3
Thanks: 1
Thanked 0 Times in 0 Posts
Default

Thank you Nicolas! I think I get it now.

I have yet another question related to setTimeout though. I see in numerous usage of setTimeout() that you create a wrapper function before passing in the function to be executed, but I don't understand why that is necessary.

For example, in the Fast-Type Support section of Chapter 8 on JSON (p.266-267 of 2nd ed.), you have:

Code:
if ( iKeyCode == 8 || iKeyCode == 46 ) {
    this.timeoutId = setTimeout( function () {
        oThis.provider.requestSuggestions(oThis, false);
    }, 250);
}
Why can't this be simply:

Code:
if ( iKeyCode == 8 || iKeyCode == 46 ) {
    this.timeoutId = setTimeout(
        oThis.provider.requestSuggestions(oThis, false),
        250);
}
 
Old March 8th, 2009, 01:11 AM
nzakas's Avatar
Wrox Author
 
Join Date: Dec 2004
Location: Peabody, MA, USA.
Posts: 217
Thanks: 0
Thanked 5 Times in 5 Posts
Default

This is because setTimeout() expects a function pointer to be passed as the first argument. In your second example, you're not passing a function pointer, you're passing the result of calling oThis.provider.requestSuggestions(this, false), which is "undefined". Again, simple examples you can play with:

Code:
function sayHi(){
    alert("hi");
}

setTimeout(sayHi, 1000);
Here, the sayHi() function isn't called until after a second has passed. By using "sayHi" without the parentheses, you're accessing the function pointer instead of calling the function. Now try this:

Code:
function sayHi(){
    alert("hi");
}

setTimeout(sayHi(), 1000);
You'll note that the alert is displayed immediately because you're calling the function instead of passing in the function pointer.
__________________
Nicholas C. Zakas
Author, Professional JavaScript for Web Developers (ISBN 0764579088)
http://www.nczonline.net/
The Following User Says Thank You to nzakas For This Useful Post:
wuman (March 8th, 2009)
 
Old March 8th, 2009, 01:45 AM
Registered User
 
Join Date: Mar 2009
Posts: 3
Thanks: 1
Thanked 0 Times in 0 Posts
Default

Thanks! That answers my question. :)




Similar Threads
Thread Thread Starter Forum Replies Last Post
Inquiry john.7250 JSP Basics 4 October 17th, 2008 03:43 PM
Inquiry john.7250 BOOK: Beginning JavaScript 3rd Ed. ISBN: 978-0-470-05151-1 1 July 22nd, 2008 08:43 AM
Ch5 Ex5_03 yetri56 BOOK: Ivor Horton's Beginning Visual C++ 2005 1 April 14th, 2008 02:36 AM
Client call back inquiry JakeSpeed ASP.NET 2.0 Basics 0 November 6th, 2006 09:55 AM
CH5 p 184 wadesmart BOOK: Beginning PHP4/PHP 5 ISBN: 978-0-7645-4364-7; v5 ISBN: 978-0-7645-5783-5 2 November 17th, 2003 04:41 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.