如何从节点js中的回调函数中断循环?

时间:2013-08-21 13:15:43

标签: node.js

我在Node.js中有异步查询。变量sq3是一个连接变量。 例如:

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();
  }
}

如何摆脱回调功能? 感谢

3 个答案:

答案 0 :(得分:5)

就这样做,使用递归而不是循环。这不仅可以让您实现所需的逻辑。它也不会立即激活一堆异步请求。它们依次执行,但是异步执行,所以它仍然具有高性能。

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());

}

您可以考虑使用类似的逻辑来限制同时发出的请求(比如每个lookAtItem调用允许10个这样的请求。这样您就可以实现两种方法的混合,然后只是优化同时请求性能的数量.Async库使得这样的事情比较容易。

答案 1 :(得分:0)

在您的代码片段中,您无法从回调函数中断开。在node.js中,回调函数稍后在同一线程上以未指定的方式运行。这意味着你回调函数执行的时间,for循环已经很久了。

要获得所需的效果,您需要非常重构代码。这是一个如何做到这一点的例子(未经测试!!)。我们的想法是继续使用项目列表调用doSomething(),每次将其缩小一个元素,直到达到所需的结果(中断条件)。

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.
        }
    }
}

答案 2 :(得分: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();
  }
}