0

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


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!

2
  • From the looks of things, you are probably going to need a closure since you want some data passed to the callback. Whether to do that closure inline or as a function "factory" depends on where xmlDom is supposed to come from. Can you clarify that point? Where does xmlDom come from? Commented Dec 19, 2008 at 17:08
  • Thanks for asking. xmlDOM is passed by jquery $.get method as argument and it is supposed to be a DOC fragment output of a aprsing activity carried out by $.get (according to what is said @page 235 in "Jqery in action" by Mannings
    – Daniel
    Commented Dec 19, 2008 at 17:58

4 Answers 4

6

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()?

4

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);
}
1

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.

0

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)

Not the answer you're looking for? Browse other questions tagged or ask your own question.