1

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--;
                    }
                });
            }
7
  • 3
    You should call itself again when you are "not done" instead of having a loop Commented Dec 16, 2016 at 0:08
  • 1
    in other words, you need to look into recursion Commented Dec 16, 2016 at 0:09
  • 2
    does bridgeCheckRooms make an async call? Commented Dec 16, 2016 at 0:10
  • I did that but the function ends up duplicating itself numerous times even if done==true so it's running more times than I need it to. Commented Dec 16, 2016 at 0:10
  • Yes the bridgeCheckRooms function does make an async call to a database for a value. @Learning2Code Commented Dec 16, 2016 at 0:11

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

5 Comments

I was doing the same thing earlier but when it finally finishes, the function is still being called. I console log done when it it goes into the success block but done is being logged more than once. I'm assuming the function is still being called even after it reaches done.
the only reason the function would be called is if reply.success is false - the only way you'd keep on getting done logged is if the callback to bridgeCheckRooms is called multiple times by bridgeCheckRooms - explain a little about bridgeCheckRooms and how the callback is used by that function
the bridge function emits a socket message with the room to be queried. after the room has been found or found empty, the server sends back an answer which is then sent back to the original function. here's the code for the bridge: function bridgeCheckRooms(send,callback){ socket.emit('room-check',send); //when room has been retrieved socket.on('room-checked'+send.id,function(reply){ callback(reply); }); } not too sure if it will format correctly
so it's not possible that socket.on('room-checked'+send.id, is being triggered more than once?
this solution works, however the function is executing more than once somehow but it indeed stops sending calls to bridgeCheckRooms after a successful reply
1

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

Comments

0

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.

2 Comments

This would be better as a comment, unless you add some code to back up your assertion that Promises would be useful
in browsers, synchronous network requests are deprecated on the main thread, so if this is browser code (and there's no indication that it's NOT) that's a poor suggestion

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.