0

I'm trying to retrieve an entire object from a Parse database, but this is not a Parse-specific problem. I'm trying to use the object's unique ID to retrieve the whole object and assign it to the resultObject variable, so that I can save a reference to the resultObject later within this same addPerk function.

What's happening is that the alert() on the final line of the block below si coming back saying that resultObject is undefined. I believe this is because the objectQuery's success function is called after the alert() line, due to the asynchronous nature. However, I thought I could fix this by making a while() loop to make the program wait until resultObject is defined. Why doesn't this work? How else could I get the resultObject out of the scope of the success function?

I don't want to move all of my remaining logic into the success block of the query, I'm already experiencing major "pyramid of death" and don't want to make the code any more difficult to read.

addPerk:     function() 
{
    var resultObject;        

    var Object = Parse.Object.extend("Object");
    objectQuery = new Parse.Query(Object);
    objectQuery.get(objectId, {
        success: function(object) {
            alert("returned object in success function is " + object);
            resultObject = object;
            alert("resultObject in success function is:" + resultObject);
        },
        error: function(object, error) {
            alert("error: " + error.code + ", " + error.message);
        }
    });

    while (typeof correctProvider == "undefined") {
        setTimeout(null, 3000);
    }
    alert("resultObject (after WHILE loop) is: " + resultObject);
jdogg
  • 268
  • 2
  • 14
  • 1
    No, you cannot do that. There's no way around callbacks. However you can use promises to avoid the pyramid, parse does support them as well. – Bergi Aug 24 '15 at 20:28
  • 1
    See http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron?rq=1 for some good answers. This is a very common StackOverflow JS question, and is not specific to backbone. – Katana314 Aug 24 '15 at 20:30

1 Answers1

0

Why doesn't this work?

while (typeof correctProvider == "undefined") {
    setTimeout(null, 3000);
}

This is your logic:

  1. Enter the while loop
  2. Set a timeout
  3. Go to 1

JavaScript loops around and around the loop setting up as many timeout handlers as it can before running out of memory.

It is too busy looping to see if any of them have ever actually timed out, or to run the success function.

How else could I get the resultObject out of the scope of the success function?

You don't.

You have to go forwards from the callback, you can't go back.

Make the callback do the work you want to do when you get the data.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Huh. I thought setTimeout was just a way to say "stop at this line" for 3 seconds. So what it's actually doing is setting a timeout and then immediately moving to the next line (which in this case is the next iteration of the while loop)? Thanks for helping, by the way! – jdogg Aug 24 '15 at 20:49
  • Yes. http://stackoverflow.com/questions/16873323/javascript-sleep-wait-before-continuing – Quentin Aug 24 '15 at 20:50
  • So why couldn't I just insert some filler logic - like "var foo = bar;" within the while() loop? I would think that eventually the success callback will be called, and at that point resultObject will not be undefined, and the loop would stop executing. – jdogg Aug 24 '15 at 20:52
  • No, because then you just add more steps between 2 and 3. The JavaScript engine will still be too busy going round and round the while loop to do anything else. The success callback will never be called, because the thread is running the while loop instead. – Quentin Aug 24 '15 at 20:53
  • So, trying to understand this structurally - the while loop is preventing the success callback from ever being called. This is because Javascript needs some "downtime" to call the success callback, and the while loop takes precedence over everything else? Otherwise, why will success be called if I'm not in a loop even though the script is still being executed? – jdogg Aug 24 '15 at 21:01
  • Actually, I just found the answer [here](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron?rq=1) Thanks again for your help! – jdogg Aug 24 '15 at 21:02
  • Yes. At some point the script will stop being executed. There will be no function that is being run. It will be finished. At that point the JavaScript engine will start looking for events and associating them functions that are registered as event listeners. – Quentin Aug 24 '15 at 21:02