简体   繁体   English

递归堆栈-Javascript

[英]Recursion stack - Javascript

I'm trying this recursion thing in Javascript, and found the numbers are printed out in the wrong order (Desc, whereas I was expecting Asc). 我正在Javascript中尝试这种递归操作,发现数字以错误的顺序打印出来(Desc,而我期望是Asc)。 Why is this, and how can I visualise the process? 为什么会这样,我如何可视化流程?

(function hi(x) {
    if (x > 1000) {
        return;
    } else {
        x+=1;
        setTimeout(hi(x), 100000);
        console.log(x);
    }
})(4)

Change your code to : 将您的代码更改为:

(function hi(x) {
    if (x > 1000) {
        return;
    } else {
        x+=1;
        setTimeout(function (){hi(x);}, 100);
        console.log(x);
    }
})(4)

change is in here: 变化在这里:

function (){hi(x);}

This : 这个 :

 setTimeout(hi(x),

Invokes the function immediately. 立即调用该功能。 you don't want that. 你不想要那个。

You want a function that will run hi(x) after 100000 ms. 您需要一个在100000 ms之后运行hi(x)函数

You though the first argument passed to setTimeout is a function, but it's not. 您虽然传递给setTimeout的第一个参数是一个函数,但事实并非如此。

When you do: 当您这样做时:

setTimeout(hi(x), 100000);

it means: 它的意思是:

  1. evaluate the expression hi(x) to get its value 计算表达式hi(x)以获得其值
  2. after 100000ms, if the value from previous step is 100000ms之后,如果上一步的值是

    • callable, call it (with arguments if passed) 可调用,调用它(如果传递则带有参数)
    • otherwise evaluate it (similar to eval ) 否则评估它(类似于eval

so it equals: 因此等于:

var ret = hi(x);
setTimeout(ret, 100000);

Apparently ret is not your function hi , but the return value of it - undefined . 显然ret不是您的函数hi ,而是它的返回值undefined So setTimout(undefined, 100000) actually does nothing meaningful - eval(undefined) after 100000ms. 所以setTimout(undefined, 100000)实际上没有任何意义-100000ms之后eval(undefined)

Strip that out, your code equals: 剥离掉,您的代码等于:

(function hi(x) {
    if (x > 1000) {
        return;
    } else {
        x+=1;
        hi(x);
        console.log(x);
    }
})(4)

What's this? 这是什么? Yes, synchronous recursive function call. 是的, 同步递归函数调用。 That's why you see the result in console is counting down rather you expected. 这就是为什么您看到控制台中的结果递减计数而不是您期望的原因。

The solutions, besides wrapping it in an anonymous function: 这些解决方案除了将其包装在匿名函数中之外:

setTimeout(function () {
    hi(x);
}, 100000);

Alternatively you can also pass extra arguments to setTimeout : 另外,您也可以将额外的参数传递给setTimeout

setTimeout(hi, 100000, x);

Arguments passed to setTimout after the delay, will be passed in hi when invoking it. 延迟后传递给setTimout参数将在调用它时传递给hi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM