3

由于我使用 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 万次递归(实际上队列已经被填满)。所以我想澄清一下,递归深度限制在 node.js 中是如何工作的。我的猜测是,如果我在那个递归调用的函数中做某事,节点就有更多的时间来释放调用堆栈,但我可能大错特错。欢迎更有经验的节点用户提供任何澄清。

4

1 回答 1

5

您的第二个示例中根本没有递归。

在第一个示例中,您显然有一个递归调用。

在第二个示例中,调用 memcacheq.set 立即返回,然后您的函数返回。当触发事件在稍后发生时,它将在函数的某处创建一个节点以调用。

--- 没有进行递归调用 ---

在稍后的某个时间点,memcache 函数将完成并将事件排队到事件队列以触发您的回调。

但请注意,这是通过事件队列中的事件完成的,而不是通过您的函数的直接递归调用,该函数可能早已返回。

于 2011-10-04T09:12:18.337 回答