Максимальная глубина рекурсии в Node.js 0,4 - PullRequest
3 голосов
/ 04 октября 2011

, поскольку я использую Node.js еще не слишком долго, я столкнулся со следующей проблемой.Я понимаю, что, используя управляемую обратным вызовом парадигму, нам нужно преобразовать циклы, которые мы использовали в синхронном коде, в рекурсию.Моя проблема в том, что я не могу понять, насколько глубокий узел может идти с рекурсией, результаты разных тестов противоречивы.Например, я попробовал код, который нашел в Интернете:

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

Он еще не закончился, но работает до сих пор для более чем 4 миллионов рекурсий (и очередь фактически заполняется).Поэтому я хотел бы уточнить, как работает ограничение глубины рекурсии в узле.Я думаю, что если я сделаю что-то в этой рекурсивно вызываемой функции, у узла будет больше времени для освобождения стека вызовов, но я могу быть совершенно неправ.Любые разъяснения от более опытных пользователей узлов приветствуются.

1 Ответ

5 голосов
/ 04 октября 2011

В вашем втором примере вообще нет рекурсии.

В первом примере у вас явно рекурсивный вызов.

Во втором примере вызывается memcacheq.set, который немедленно возвращается, а затем возвращается ваша функция.Он должен был сделать узел где-то из функции для вызова, когда вызванное событие произойдет в более позднее время.

--- Не было сделано рекурсивного вызова ---

В какой-то момент вЧерез некоторое время функция memcache завершит работу и поместит событие в очередь событий, чтобы вызвать ваш обратный вызов.

Но учтите, что это делается из события в очереди событий, а НЕ прямым рекурсивным вызовом из вашей функции, которыйвероятно, давно вернулся.

...