0

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

如何摆脱回调函数?谢谢

4

3 回答 3

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 库制作这样的东西更轻松。

于 2013-08-21T14:00:52.283 回答
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.
        }
    }
}
于 2013-08-21T13:56:54.350 回答
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();
  }
}
于 2021-04-19T10:11:38.000 回答