Javascript: settimeout recursion endless stack increase?

送分小仙女□ 提交于 2021-01-27 19:10:33

问题


My goal is a slideshow of background images with HTML/CSS/JS. Many solutions that I've found promote something like this:

my_recursion();

function my_recursion () {
 // cycle the Background image ...
 setTimeout(my_recursion, 3000);
}

Am I wrong to assume that this is bad style? I would expect that at e.g. cycle 1000 all the other 999 instances of my_recursion are still open / on the stack? Doesn't this create and infinite stack which consumes more and more memory?

Or is there some sort of intelligence involved which does something like "if a function calls itself at the end, the (n-1)th function is destroyed including all variables that were assigned inside of it"?


回答1:


This will not result in endless stack increase, because of the way setTimeout works, and imho it is not bad style.

setTimeout does not guarantee that code will run directly after the given timeout. Instead, after that timeout it will push the callback onto a "queue", which will be processed when the stack is empty. So it will only run when my_recursion has returned and the stack is empty.

If a function calls itself at the end (...)

my_recursion doesn't call itself anywhere. It just passes itself as an argument to setTimeout. After that, it will just continue executing, return directly after, and will be popped from the stack.

This presentation explains the stack and the event queue.




回答2:


In your question, your function does not have any parameters. In a real implementation, I hope you plan to use them.

const cycleBackground = (elem, bgs = [], ms = 1e3, i = 0) =>
  ( elem.setAttribute ('style', bgs[i])
  , setTimeout
      ( cycleBackground      // function to schedule
      , ms                   // when to schedule, ms from now
      , elem                 // user-specified element to change
      , bgs                  // user-specified backgrounds
      , ms                   // user-specified delay
      , (i + 1) % bgs.length // next background index
      )
  )

const backgrounds =
  [ "background-color: red;"
  , "background-image: linear-gradient(45deg, cyan 0%, purple 75%);"
  , "background-color: green;"
  ]

// call site
cycleBackground
  ( document.body // element to target
  , backgrounds   // list of backgrounds
  , 3e3           // delay, 3 seconds
  )
p {
  text-align: center;
  font-size: 3vw;
  font-weight: bold;
  color: white;
}
<p>Wait 3 seconds...</p>



回答3:


The code is fine. It destroys all the variables because when you call it first time. It setTimeout() for the next function and at last return. You function doesnot return the the next.

my_recursion();

function my_recursion () {
 // cycle the Background image ...
 setTimeout(my_recursion, 3000); //Sets timeout for next function.
 //returns undefined here
} 


来源:https://stackoverflow.com/questions/54443801/javascript-settimeout-recursion-endless-stack-increase

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!