在执行下一行代码之前,我不知道为什么我的程序没有完成递归函数。
console.clear();
var a = 1;
function logA() {
if (a<11) {
console.log(a);
a++;
setTimeout(logA, 100);
}
else {
return;
}
}
logA();
console.log("after set timeout");
样品: https://jsbin.com/moyanudeki/edit?js,console
堆栈中发生了什么?
答案 0 :(得分:2)
这里没有递归。 setTimeout
,顾名思义,在设定的时间(在这种情况下为100ms)到期后,为异步执行安排一个函数。这并不能阻止当前批次的代码运行。
即。 logA()
将返回,控制台打印"after set timeout"
,然后VM等待100ms到期。当发生这种情况时,它会执行logA()
,再次安排自己,依此类推。
为了清楚起见,这个将是递归:
console.clear();
var a = 1;
function logA() {
if (a<11) {
console.log(a);
a++;
logA();
}
else {
return;
}
}
logA();
console.log("after recursion");
答案 1 :(得分:1)
第一次调用logA()
函数时,if
块按预期执行。第一次调用setTimeout(logA, 100);
。
在Javascript setTimeout()
中异步运行,因此它将在堆栈中等待100ms,并执行下一个console.log("after set timeout");
语句。执行此第一次超时后的logA函数,触发一次超时等等。
所以你的输出符合预期:
1
"after set timeout"
2
3
4
5
6
7
8
9
10
答案 2 :(得分:1)
也可能有兴趣了解堆栈在javascript中的行为是如何理解事件循环。在javascript中,首先清空堆栈,然后执行异步回调,这些回调堆叠在事件队列中。
在您的示例中,我们有以下代码:
function test () {
console.log('first log');
}
setTimeout(test, 0);
console.log('last log');
现在,在事件队列中传递函数对象测试。清除堆栈后,此功能将被执行。
但是如果你像这样执行directy函数:
function test () {
console.log('first log');
}
setTimeout(test(), 0);
console.log('last log');
现在将直接执行功能代码,并且该功能不会在事件队列中结束。
希望这很有帮助