1. Обычная рекурсия.
function pow(x, n) {
if (n != 1) {
return x * pow(x, n - 1);
} else {
return x;
}
}
console.log( pow(2, 3) );
2. Рекурсия с использование метода setTimeout.
var timerId = setTimeout(function tick(a) {
if ( 0 < a ) {
console.log( "тик" );
timerId = setTimeout(tick, 2000, a - 1);
} else {
clearInterval(timerId);
}
}, 2000, 5);
console.log(window);
На втором изображении выделилась 4 строка, ибо я попробовал выбрать определенный вызов в stack, но меня не переместило в него, и все так же показывает последнее контекст. Еще я обратил внимание что в Call Stack указано setTimeout(async).
3. Попробовал реализовать рекурсию как в первом примере с использованием setTimeout.
setTimeout(function tick(a) {
if (0 < a) {
console.log("тик");
return 2 * setTimeout(tick, 2000, a - 1);
} else {
return 123;
}
}, 2000, 2);
console.log(window);
Я хотел сделать глубокую рекурсию через setTimeout, и посмотреть будет ли выход из нее, но этого не произошло.
Итог:
1. С первым примером все ясно.
2. Здесь мне не понятно зачем нужны стеки, если их нельзя просмотреть.
3. В этом примере хотел сделать рекурсию через setTimeout частью выражения, что бы потом вернуть значение через стек, но этого не произошло, так как сборщик мусора все зачистил. Я предполагаю, что как только таймер перестает быть актуальным, то сборщик мусора сразу ее чистит, но мне все равно не понятно почему он игнорирует тот факт, что вызов был в контексте выражения return 2 * setTimeout(tick, 2000, a - 1);, и оно по идеи ждем результата как в первом пункте. Вот более наглядный пример в статье.
P.S: В третьем пункте итогов было заблуждение, и в следствии он полностью ошибочный:
3. В этом примере хотел сделать рекурсию через
setTimeoutчастью выражения, что бы потом вернуть значение через стек, но этого не произошло, так каксборщик мусоравсе зачистил. Я предполагаю, что как только таймер перестает быть актуальным, тосборщик мусорасразу ее чистит, но мне все равно не понятно почему он игнорирует тот факт, что вызов был в контексте выраженияreturn 2 * setTimeout(tick, 2000, a - 1);, и оно по идеи ждем результата как в первом пункте. Вот более наглядный пример в статье.
return 2 * setTimeout(tick, 2000, a - 1); возвращает id - числовой идентификатор таймера, но по мима получения id опять происходит вызов.




setTimeoutнет никакого стэка. – Nov 07 '17 at 03:00setTimeout(tick, 2000, a - 1), а значит стек не должен очиститься пока этот вызов не вернет что либо, но так как тут используется методsetTimeout, то и работает это возможно по другому, по этому и задал вопрос, что бы пояснили. На счет стека уsetTimeout, я глаголил исходя увиденного в консоли, а в ней он есть. – Виталик Черный Nov 07 '17 at 03:19setTimeout. – Виталик Черный Nov 07 '17 at 03:25returnвнутри функции, поданной вsetTimeout? Куда она что-то возвращает? Никакого результатаsetTimeoutне ждет. Обдумайте понятие "асинхронность", помедитируйте. – Nov 07 '17 at 04:28