Javascript:嵌套回调/MySQL 结果
我确信这是一个基本问题,但我已经在谷歌上搜索了一段时间,找不到满意的答案。
我习惯于在 PHP 中编写 MySQL 选择查询,并简单地获取结果,循环遍历每一行,然后在循环根据每个单独行的列值进行进一步查询。
但是,我现在正在使用 javascript 服务器端代码,该代码依赖于一个 SQL 对象,您可以在其中传递查询,然后传递一个回调函数,该函数将在查询运行后调用。
我对一些范围界定问题以及如何最好地干净地做到这一点感到困惑。例如,我不想做类似的事情:
SQL.query("select * from blah", function(result) {
for(var i = 0; i < result.length; i++) {
SQL.query("select * from blah2 where i =" + result[i].property, function(result2) {
//now how do I access result from here? I know this isn't scoped correctly
});
}
});
编写这种嵌套 SQL 查询样式并且没有范围问题/混乱代码的标准方法是什么?谢谢!
I am sure this is a basic question, but I have been searching google for awhile and can't find a satisfactory answer..
I am used to programming MySQL select queries in PHP and simply grabbing a result, looping through each row, and within the loop doing further queries based on the column values of each individual row.
However, I'm working with javascript server side code now that relies on a SQL object where you pass the query and then a callback function that will be invoked after the query is run.
I'm confused with some of the scoping issues and how to best cleanly do this. For example, I don't want to do something like:
SQL.query("select * from blah", function(result) {
for(var i = 0; i < result.length; i++) {
SQL.query("select * from blah2 where i =" + result[i].property, function(result2) {
//now how do I access result from here? I know this isn't scoped correctly
});
}
});
What is the standard way to write this style of nested SQL query and not have scoping issues/messy code? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这非常有趣...我从未听说过“服务器端 javascript”...但这可能有助于组织您的代码。我使用这个方法来组织我的 ajax 请求回调。
使用你的例子,它看起来像这样。
上面的代码不存在范围问题 - 但这是我喜欢组织此类事情的好方法。
This is very interesting... I've never heard of "server-side javascript"... but none the less this might help organize your code a bit. I use this method to organize my ajax request callbacks.
using your example it would look like this.
There are no scoping issues with your above code - but this is a nice way I like to organize this kind of thing.
结果
将在第二个回调中可用,这就是闭包 在 JavaScript 工作中,函数可以访问定义它的外部作用域中的所有变量。现在,问题来了,
i
不会指向正确的值,它也将继承到第二个回调,但它是引用,因此将具有错误的值。修复方法是创建另一个闭包:
或者一个额外的函数:
result
will be available in the second callback, that's how closures in JavaScript work, the functions has access to all variables in the outer scopes it was defined in.Now, on to the problem,
i
will not point to the correct value, it too will be inherited to the second callback but it`s a reference and will therefore has the wrong value.Fix is to create another closure:
Or an extra function:
由于您使用的是服务器端 Javascript,因此您可以使用
forEach
。假设result instanceof Array == true
:如果
result
只是类似数组,那么这应该可以解决问题。
Since you are using server-side Javascript, you can likely use
forEach
. Assuming thatresult instanceof Array == true
:If
result
is merely array-like, then thisshould do the trick.
正如其他人指出的,
结果
实际上将在嵌套回调中一直可用。但这有一个非常棘手的部分:
...因为嵌套查询异步运行,您的代码实际上会触发一堆并行查询 - 每个查询一个
结果
中的行——所有内容同时运行(!)。这几乎肯定不是您想要的;除非结果
确实非常小,否则所有并发查询将很快耗尽所有可用的数据库连接。为了解决这个问题,您可以使用如下内容:
上面的代码将一次运行 1 个嵌套查询。如果您需要的话,可以很容易地调整上述内容以引入有限的并行性(例如一次 4 个)——尽管这可能没有必要。
As others have pointed out
result
actually will be available all the way down in the nested callback.But there is a very tricky part to this:
...Because the nested query runs asynchronously, your code will actually fire off a bunch of parallel queries -- one for each row in
result
-- all running at the same time (!). This is almost certainly not what you want; and unlessresult
is very small indeed, all the simultaneous queries will use up all your available db connections rather quickly.To remedy this, you might use something like this:
The above will run your nested queries 1-at-a-time. It's fairly easy to adapt the above to introduce limited parallelism (eg. 4-at-a-time), if you want it -- though it's probably not necessary.