简体   繁体   中英

Javascript callback within a while loop does not work?

I'm trying to make an event driven while loop in javascript. Essentially it iterates through an array of values and makes a query during each iteration. Then, based on the result of the query it should either keep looping or stop and do something.

I realize that you can't have callbacks in a while loop so I'm confused on how to even implement such a thing. Nested functions repeat themselves and that's not ideal.

my loop code:

             var done = false;
             while(!done){
                bridgeCheckRooms(send,function(reply){ //callback
                    console.log(tagArray[count]);
                    console.log(reply);
                    if(reply.success){
                        done = true;
                    } else {
                        count--;
                    }
                });
            }

You should use recursion. An approach to that would be something like this:

     function next() {

            // ....

            bridgeCheckRooms(send,function(reply){ //callback
                console.log(tagArray[count]);
                console.log(reply);
                if(reply.success){
                    // continue() ?
                    // done = true;
                } else {
                    count--;
                    next();
                }
            });
     }

     next();

Of course this is just an example. You should adapt it to you entire code.

Your code would be correct if bridgeCheckRooms was synchronous and blocked the thread of execution until the response was returned. See this SO post on synchronicity

Here is what is happening in your code:

The code block in your while loop is executing bridgeCheckRooms which we will assume does some work, then queues an asynchronous call to the database. bridgeCheckRooms will then return, and execution of your while loop will immediately continue, and queue up yet another call to bridgeCheckRooms .

They key piece is that bridgeCheckRooms is an asynchronous function, and doesn't block execution until it is finished. So when you call bridgeCheckRooms, it simply queues an asynchronous call, but doesn't wait until it completes.

So if your while loop executes 10 times, you will have 10 pending requests to the database. But those requests won't get to execute until the while loop stops executing and yields execution for the asynchronous queue to execute.

@pablo has the right code approach for this. The difference between his code and your code, is that a second asynchronous call is not made until the first asynchronous call has completed.

Edit: CallbackHell.com looks like a great primer on this topic

I think you want to look into deferred objects and promises. You want to wait until the async call is done to make your check to see if you need to keep looping.

Or you could make it a synchronous call if there is not benefit to the async here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM