(function repaint(){
//重绘相关代码
setTimeout(repaint,16) ;
})() ;
或者
(function repaint(){
//重绘相关代码
requestAnimationFrame(repaint) ;
})() ;
我在函数内部加了断点,在chrome里面查看call stack,始终是一层,这是否能证明一个函数,在setTimeout和requestAnimationFrame内调用自己不造成递归?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
答案是不会。
首先我们来理解一下什么叫递归,先不贴wiki上的说明了,大家普遍认识是,递归就是函数自身调用自身。这里面很重要的一点就是,在调用自身的过程中,父函数是没有退出的。需要等被调用的子函数退出后父函数才退出。
但是setTimeout函数不是这样执行的,它只是创建了一个定时任务,然后直接退出了,javascript的引擎线程会将这个任务放到自己的定时任务中,当定时结束后才调用子函数。
可以参考下图(来源于网络)
详细可以参考:谈谈JavaScript的异步实现
不会。因为当前函数执行完毕才会去处理超时处理函数。
这个分逻辑上和实现上。
lz可以这么认为,这种异步形式的递归,不会导致栈空间的溢出。但是作为副作用,这种递归不能依靠异步调用的返回值执行操作(当然,后面可以有操作,但是无法利用到返回值)。和尾递归很像呢,至少在逻辑上两者也确实非常接近。
setTimeout是“异步”执行的(在我看来其实是伪异步,JS是单线程的,所谓的异步只是通过适当地插入到代码执行队列中延迟执行而已),其实总体相当于在一段时间内定期执行一次repaint函数而已。只不过第一次是立刻执行罢了。
可以叫循环,但不能叫递归
虽然称不上递归,但还是感觉repaint这个方法会被调用多次的。
每隔一段时间生产一个settimeout对象也会有开销的吧