JS waits for callback to complete inside for loop

I have an array of 3 data that I need to insert into pouchdb

, so I am using for loop

to insert data, but the problem is that this is not inserting full data, because the loop ends before the callback.

for(var i=0;i<data.length;i++){
   var jsondoc=doc1;//document
    console.log(i)  //getting console for all data. eg:1,2,3
    console.log(data[i])//getting console for all data. eg:hi, hello

    jsondoc.messages.push({msg: data[i]});   //updating message, here need to be done somthing           
                      db.put(jsondoc, function(err2, response2){
                         if (err2) { console.log(JSON.stringify(err2)); }
                            console.log("this is not repeating") ;                                    
                       });

}

      

+3


source to share


2 answers


Since db insertion

async works, you cannot put the loop on hold until the operation completes. One thing you can do is serialize db inserts

with a helper function like this:

function insertItem(data, i, completeCallback) {
    // check if we still have items to send
    if(i < data.length) {
        var jsondoc=doc1;//document
        //updating message, here need to be done somthing
        jsondoc.messages.push({msg: data[i]});   
        db.put(jsondoc, function(err2, response2){
            if (err2) { 
                console.log(JSON.stringify(err2)); 
            } 
            // recursively call to push the next message
            insertItem(data, i+1, completeCallback);
        });
    } else {
        // no more items to send, execute the callback
        if(typeof completeCallback === "function") {
            completeCallback();
        }
    }
}

      

You will need to update your code to pass that code to the function callback instead of continuing execution after the function call pushMessage

, so if your original code looks like this:

// ... code before the loop
for(var i=0;i<data.length;i++){
    // ... original body of the loop
}
// ... code to execute after the loop and that currently causes problems

      

you need to change it like this:



// ... original code that was before the loop
insertItem(data, 0, function() {
    // ... original code hat was executed after the loop and that caused problems
    // but now it gets executed after all items were inserted in db
}

      

Another alternative would be to send all inserts in parallel and execute join()

for those operations; you still need a callback workaround. Something like lines:

function insertItems(data, callback) {
    var remainingItems = data.length;
    if(remainingItems === 0 && typeof callback === "function") {
        callback();
    }         
    for(var i=0;i<data.length;i++){
        var jsondoc=doc1;//document
        console.log(i)  //getting console for all data. eg:1,2,3
        console.log(data[i])//getting console for all data. eg:hi, hello

        jsondoc.messages.push({msg: data[i]});   //updating message, here need to be done somthing           
        db.put(jsondoc, function(err2, response2){
            if (err2) { console.log(JSON.stringify(err2)); }
            remainingItems--;
            if(remainingItems === 0 && typeof callback === "function") {
                // I know, code redundancy :P
                callback();
            }                                     
        });

    }
}

      

The use of this second function is the same as for insertItem

.

+1


source


If you understand correctly, your problem is related to the problem. jsondoc or data [i], or whichever variable is causing the problem, is changed before the callback completes.

Take a look at the jsFiddle which shows how to solve such a problem.



for(var i = 0; i < 3; i++){
    (function(){
        var j = i;
        setTimeout(function(){
            callback(j)
        }, 500);
    })();
}

      

If you look at the js console when running jsFiddle, you can see that the first loop prints 3 times 3, which is the finish value for i. Whereas the second, where we store the value for the new variable in the new scope, outputs 1, 2, 3 as expected.

+1


source







All Articles