0

I have asynchronous query in Node.js. Variable sq3 is a connection variable. For example something like this:

for (var i in res) {
  if (i == 1) {
    sq3.query("SELECT * from students;",

      function (err, res) {
        if (err) {
          throw err;
        } else {
          if (res.length == 1) {
            //do something
          } else {
            //break for
          }
        }
      });

    sq3.end();
  }
}

How can I break from callback function? Thanks

7
  • I want to break loop for, not just return from callback function Commented Aug 21, 2013 at 13:22
  • then simple break statement should have worked for that Commented Aug 21, 2013 at 13:34
  • I've already tried all that simple ways and it doesn't work Commented Aug 21, 2013 at 13:43
  • simple break doesn't work because it is callback function and loop for is outside that function Commented Aug 21, 2013 at 13:45
  • 3
    It's not possible, but it's also pointless to try to break a loop from an async callback... The loop will be done by the time any callback gets the chance to run edit: assuming sq3 is async Commented Aug 21, 2013 at 13:47

3 Answers 3

5

Just do it like this, using recursion instead of loops. Not only does this allow you to achieve the logic you want. It also doesn't spin up a bunch of async requests at once. They execute in turn, but asynchronously, so it's still performant.

function lookatEntireResponse(res) {

    function lookAtItemInResponse(item) {
        if(item == 1) {
            sq3.query("SELECT * from students;",

                function(err, res) {
                    if (err)
                    {
                       throw err;
                    }

                    else
                    {
                        if(res.length==1)
                        {
                            doSomething(item);
                            lookAtItemInResponse(res.shift());
                        }
                        else
                        {
                           //just don't call the next lookAtItemInResponse function, effectively same thing as "break;"
                        }

                    }
                });

            sq3.end();
        } else {
            lookAtItemInResponse(res.shift());
        }
    }

    lookAtItemInResponse(res.shift());

}

You can consider throttling simultaneous requests with similar logic (say allowing 10 such requests per lookAtItem call. This way you can achieve a hybrid of the two methods, and then just optimize the number of simultaneous requests for performance. The Async library makes stuff like this easier.

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

Comments

0

In your code fragment, you can't break from the within the callback function. In node.js, callback functions run at an unspecified later time on the same thread. This means but the time you callback function executes, the for loop has long since finished.

To get the effect you want, you need to restructure you code quite significantly. Here's an example of how you could do it (untested!!). The idea is to keep calling doSomething() with the list of items, shrinking it by one element each time until the desired result is achieved (your break condition).

function doSomething(res)
{
    while (res.length > 0)
    {
        i = res.shift(); // remove the first element from the array and return it
        if (i == 1)
        {
            sq3.query("SELECT * from students;",
                function(err, res) {
                    if (err)
                    {
                       throw err;
                    }

                    if (res.length==1)
                    {
                        //do something

                        // continue with the remaining elements of the list
                        // the list will shrink by one each time as we shift off the first element
                        doSomething(res);
                    }
                    else
                    {
                        // no need to break, just don't schedule any more queries and nothing else will be run
                    }
                });

            sq3.end();
            break; // break from the loop BEFORE the query executes. We have scheduled a callback to run when the query completes.
        }
    }
}

3 Comments

The iterative loop is just to locate items equivalent to 1, which are then queried in the database. Once the database query completes it either terminates or continues iterating through the remaining elements until it finds another equal to 1. So I'm quite sure it is equivalent.
Actually I've just realised that the res variable passed in to the original function is then reused as a parameter to the query callback function. I didn't notice the same variable name was being reused, so my code won't above work as it is. I'm not sure what the OP was trying to achieve, but my basic solution of recursively shifting through the list still holds!
Yes, now you see it. I was just double checking myself. Your logical idea is correct, and actually equivalent to mine. Your iterative loop addition(if combined correctly with the recursion to not re-visit values) may actually help performance(microoptimization). And you did mention it was untested, so I'll give you that one :) If you edit your answer in a silly way, I'll remove my downvote given that comment
0
for (var i = 0; i < res.length; i++) {
  if (i == 1) {
    sq3.query("SELECT * from students;",

      function (err, res) {
        if (err) {
          throw err;
        } else {
          if (res.length == 1) {
            //do something
          } else {
            i = res.length
          }
        }
      });

    sq3.end();
  }
}

2 Comments

Can you add an explanation in addition to your code snippet?
the question is that, he want to break the outer loop inside the sq3.query() callback. But 'break' keyword not working inside callback function. So without break statement the outer loop only break when this "i < res.length" condition false. Thats way I am changing the "i" value with the res.length, that is inside else block "i = res.length"

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.