views:

296

answers:

5

I discovered to have some problem to fully understand callbacks scoping when trying to learn Jquery. I would add that i have little experience with the Javascript language The code:

var globDom;    // placeholder for DOM fragment

// Getting xml file; jquery parses the file and give me back a DOM fragment
// saveXML is the callback

$.get(requestTarget, {}, saveXML);

// the globDom here is UNDEFINED !

alert(globDom);

// the callback

function saveXML(xmlDom)
{
    globDom = xmlDom;
}

I am sure that here there is a BIG misunderstanding by me ...

Have any suggestion?

Thanks

Daniel

+6  A: 

I haven't used jquery myself, but my understanding is that a lot of the stuff it does is asynchronous. That get method probably doesn't call your callback immediately. You'll need to wait until after the callback has been run before you try accessing globDom.

Try putting an alert within your callback method. Does that one happen before or after the alert your put after get()?

Herms
+1  A: 

I think your scoping is fine. saveXML creates a closure, which includes globDom in the scope. A closure, in case you're not familiar with the term, means that the scope that a function is defined in is included in the scope of that function's body. This means because globDom is in the scope that saveXML was defined in, the body of saveXML can access the same instance of globDom as the alert that's defined above it.

I think your actual problem lies in the fact that $.get isn't syncronous. $.get is returning immediately, before the fetch completes, which means alert gets called before the callback has run. Instead, you can use $.ajax, and set the "async" option to false, which will make $.ajax call not return until the server request succeeds.

However, the best solution is to make your code asyncronous, such that you relinquish control back to the browser, so the user can still interact with the page while they're waiting for the server request to complete.

Scotty Allen
A: 

What Herms said. your (simplified) timeline looks like

0.001 globdom = undefined;
0.002 $.get(somerequest, callback)
0.003 alert(globdom)

.. 50 milliseconds later ..

0.053 saveXml(xmlDom)
Jimmy
+4  A: 

Basically, you need to put any code which works with the returned data either in the callback itself or in functions called from the callback, because the data doesn't exist until then.

For example:

// Getting xml file; jquery parses the file and give me back a DOM fragment
// saveXML is the callback

$.get(requestTarget, {}, saveXML);

// the callback

function saveXML(xmlDom)
{
    // the xmlDom here is DEFINED !

    alert(xmlDom);
}
Ben Blank
+1  A: 

Ah-Ah. Very clear, I understand perfectly the error in my assumption: i forgot to take in account the time lag between the access time to the data (previous!) and the time at which content becomes available. A quite serious flaw - batch programming biased :-( The problem is clear and I can now address it properly. Many, many thanks for responding!

Daniel