Node.js 0.4 中的最大递归深度
由于我使用 Node.js 的时间还不太长,所以我遇到了以下问题。我知道,使用回调驱动的范例,我们需要将同步代码中使用的循环转换为递归。我的问题是我无法理解递归的节点可以有多深,不同测试的结果不一致。例如,我尝试了在 Web 上找到的代码:
var depth = 0;
(function recurseBaby() {
// log at every 500 calls
(++depth % 500) || console.log(depth);
// bail out ~100K depth in case you're special and don't error out
if (depth > 100000) return;
recurseBaby();
})();
在 18500 次递归后,它给了我节点异常(最大递归深度)。 所以我尝试添加一些功能,例如使用队列:
var depth = 0,
Memcached = require('memcached'),
memcacheq = new Memcached('127.0.0.1:22201');
(function recurseBaby() {
// log at every 500 calls
(++depth % 500) || console.log(depth);
// bail out ~10M depth in case you're special and don't error out
if (depth > 10000000) return;
memcacheq.set('test_queue', 'recurs' + depth, 0, function (error, response) {
return recurseBaby();
});
})();
它尚未完成,但到目前为止可以进行超过 400 万次递归(并且队列实际上已满)。所以我想澄清一下,递归深度限制在节点中是如何工作的。我的猜测是,如果我在递归调用的函数中执行某些操作,节点将有更多时间来释放调用堆栈,但我可能大错特错了。欢迎更有经验的节点用户提出任何澄清。
as I use Node.js for not too long time yet, I've ran into a following problem. I understand that using callback-driven paradigma we need to convert loops we used in synchronous code into recursion. My problem is I cannot understand how deep node can go with recursion, results with different tests are inconsistent. For example, I tried code I've found on Web:
var depth = 0;
(function recurseBaby() {
// log at every 500 calls
(++depth % 500) || console.log(depth);
// bail out ~100K depth in case you're special and don't error out
if (depth > 100000) return;
recurseBaby();
})();
It gives me node exception (max recursion depth) after 18500 recursions.
So I tried to add some functionality, like working with queue:
var depth = 0,
Memcached = require('memcached'),
memcacheq = new Memcached('127.0.0.1:22201');
(function recurseBaby() {
// log at every 500 calls
(++depth % 500) || console.log(depth);
// bail out ~10M depth in case you're special and don't error out
if (depth > 10000000) return;
memcacheq.set('test_queue', 'recurs' + depth, 0, function (error, response) {
return recurseBaby();
});
})();
It didn't finish yet, but works so far for more than 4 million recursions (and queue is actually getting filled). So I would like to clarify, how recursion depth limit works in node. My guess would be that if I do something in that recursively called function, node has more time to free call stack, but I may be terribly wrong. Any clarifications from more experienced node users are welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的第二个示例中根本没有递归。
在第一个示例中,您显然有一个递归调用。
在第二个示例中,调用 memcacheq.set 立即返回,然后您的函数返回。当触发事件稍后发生时,它将在函数的某个位置创建一个节点来调用。
--- 没有进行递归调用 ---
在稍后的某个时间点,memcache 函数将完成并将一个事件排队到事件队列中以触发您的回调。
但请注意,这是通过事件队列中的事件完成的,而不是通过函数的直接递归调用来完成,该函数可能早已返回。
There is no recursion in your second example at all.
In the first example you clearly have a recursive call.
In the second example a call is made to memcacheq.set which returns immediately, and then your function returns. It will have made a node somewhere of the function to call when the triggered event happens at some later time.
--- No recursive call has been made ---
At some point in time later the memcache function will finish and queue an event to the event queue to trigger your callback.
But note that this is done from an event in the event queue, NOT by a direct recursive call from your function which has probably long since returned.