2

I have this JavaScript code that iterates through an indexedDB object store and returns all of the objects it contains.

I need to wait until the method is finished before I continue on with my code because I need to make use of the array variable that the code will be pushing the objects to.

One way to ensure synchronous execution is to nest call back functions.

Rather than doing that though, I thought I could just add a while loop that iterates indefinitely to the end of the method and breaks when the variable I need has been filled.

 function getAllObjects(){
    var tags=[];
    var openRequest = indexedDB.open("Tags",CURRENT_DB_VERSION);
    openRequest.onsuccess = function(event){
        var db = event.target.result;
        var objectStore = db.transaction("domains").objectStore("domains");
        objectStore.openCursor().onsuccess= function(event){
            var cursor= event.target.result;
            if(cursor){
                console.log(cursor.value);
                tags.push(cursor.value);
                cursor.continue();
            }
        }
        db.onerror = function(event){
            console.log("an error bubbled up during a transaction.");
        };
    };
    openRequest.onerror = function(event){
        console.log("error opening DB");
    };  
    while(tags.length==0){//wait for async to finish    
    }
    return tags;
}

When I do this though, my code never exits the while loop. Why is this?

Luke
  • 5,567
  • 4
  • 37
  • 66
  • 2
    Use promises instead. See bluebird.js. – Aadit M Shah May 17 '15 at 02:55
  • 1
    For the general question: [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Qantas 94 Heavy May 17 '15 at 03:04
  • you can't make async sync, but you can go the other way. – dandavis May 17 '15 at 05:31

1 Answers1

4

JavaScript is run with a single thread, so your while loop will use up a lot of CPU and basically freeze all other computations. Promises are one approach you can use (as mentioned in a comment). You can also pass in an object with a callback to your function. In sum, forget about "sleeping" (which your loop is doing) in a single-threaded environment.

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Victory
  • 5,811
  • 2
  • 26
  • 45
  • 1
    So the reason the code isn't working is because even though I defined the onsuccess callback, the while loop halts the program BEFORE the callback gets executed. (because its all run in a single thread) – Luke May 17 '15 at 03:08
  • 1
    Basically. The engine is trying frantically to complete the while loop, but there isn't really anyway it can do that because it is deadlocked. To end the while loop you need the `onsuccess` to run, for the `onsuccess` to run you need the while loop to end. – Victory May 17 '15 at 03:11
  • Note that inline code spans (`like this`) [shouldn't be used for highlighting](http://meta.stackoverflow.com/q/254990), only for code in sentences. – Qantas 94 Heavy May 17 '15 at 04:30