javascript - 一个函数在setTimeout里调用自身会造成递归吗?
高洛峰
高洛峰 2017-04-10 13:08:39
[JavaScript讨论组]
    (function repaint(){
        //重绘相关代码
        setTimeout(repaint,16) ;
    })() ;

或者

    (function repaint(){
        //重绘相关代码
        requestAnimationFrame(repaint) ;
    })() ;

我在函数内部加了断点,在chrome里面查看call stack,始终是一层,这是否能证明一个函数,在setTimeout和requestAnimationFrame内调用自己不造成递归?

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(7)
迷茫

答案是不会。
首先我们来理解一下什么叫递归,先不贴wiki上的说明了,大家普遍认识是,递归就是函数自身调用自身。这里面很重要的一点就是,在调用自身的过程中,父函数是没有退出的。需要等被调用的子函数退出后父函数才退出。
但是setTimeout函数不是这样执行的,它只是创建了一个定时任务,然后直接退出了,javascript的引擎线程会将这个任务放到自己的定时任务中,当定时结束后才调用子函数。
可以参考下图(来源于网络)

详细可以参考:谈谈JavaScript的异步实现

PHP中文网

不会。因为当前函数执行完毕才会去处理超时处理函数。

ringa_lee

这个分逻辑上和实现上。

  • 逻辑上来说,它和递归是等价的。
  • 但是实现上,它是异步执行的,不会导致栈在使用上的无限增加,因为之前的函数执行完就销毁了。

lz可以这么认为,这种异步形式的递归,不会导致栈空间的溢出。但是作为副作用,这种递归不能依靠异步调用的返回值执行操作(当然,后面可以有操作,但是无法利用到返回值)。和尾递归很像呢,至少在逻辑上两者也确实非常接近。

天蓬老师

setTimeout是“异步”执行的(在我看来其实是伪异步,JS是单线程的,所谓的异步只是通过适当地插入到代码执行队列中延迟执行而已),其实总体相当于在一段时间内定期执行一次repaint函数而已。只不过第一次是立刻执行罢了。

PHPz

可以叫循环,但不能叫递归

PHP中文网

虽然称不上递归,但还是感觉repaint这个方法会被调用多次的。

伊谢尔伦

每隔一段时间生产一个settimeout对象也会有开销的吧

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号