在没有堆栈溢出的情况下在 javascript 中执行无限动画的模式
Posted
技术标签:
【中文标题】在没有堆栈溢出的情况下在 javascript 中执行无限动画的模式【英文标题】:Pattern to do infinite animation in javascript without stack overflow 【发布时间】:2013-02-25 13:57:26 【问题描述】:我有以下模式重复动画(本身由 x 帧组成), t 次:
sprite.prototype.loop = function(t,animation_name,frame_delay)
if(t > 0)
function next_run()
this.loop(t-1,animation_name,frame_delay);
this.run(animation_name,frame_delay,next_run);
;
sprite.prototype.run = function(animation_name,frame_delay,frame_count,callback)
frame_count ||= 0;
var s = this;
if(frame_count < this.paths[animation_name].length) // x frames
setTimeout( function ()
s.blit(s.paths[animation_name][frame_count]);
s.run(animation_name,frame_delay,frame_count+1);
, frame_delay );
else
if(!!callback) callback();
super_mario.loop(10000,'mushroom_death',40);
很明显,如果 x*t 大于最大堆栈深度,就会发生堆栈溢出。
问题:这种模式可以扩展到无限次运行动画的情况,还是有更正确的方法来处理无限循环的情况?
【问题讨论】:
【参考方案1】:我会重写你的loop
函数如下:
sprite.prototype.loop = function (t, animation_name, frame_delay)
var s = this;
var frames = s.paths[animation_name];
var x = frames.length;
for (var i = 0; i < t; i++)
for (var frame_count = 0; frame_count < x; frame_count++)
setTimeout(function (frame_count)
s.blit(frames[frame_count]);
, (i * x + frame_count) * frame_delay, frame_count);
;
就是这样。不会有任何堆栈溢出,因为没有递归。
编辑: 正如刚才提到的,您的代码还有另一个问题。两个相同的帧之间不会有任何延迟,因为您实际上为所有相同的帧同时调用setTimeout
。因此,无论t
的值是多少,动画都只会出现一次。
【讨论】:
连续设置这么多setTimeout
s 是否存在(内存/执行)问题?
存在setTimeout
无法保证在给定延迟时执行操作的问题。相反,渲染器应该查看时间并在requestAnimationFrame
循环中决定它应该在哪个帧上。这样,如果有人要最小化窗口或切换选项卡然后返回,渲染将在正确的位置继续。【参考方案2】:
setTimeout
不继承调用者的堆栈帧,所以你只需要担心 t
在这里,虽然没有理由不能简单地迭代地编写,这样堆栈大小就不是一个关注:
sprite.prototype.loop = function(t, animation_name, frame_delay)
while (t--)
this.run(animation_name, frame_delay);
;
但是,感觉这段代码并没有按照您的预期进行。这实际上是并行运行动画t
次,因为run
中的setTimeout
调用将相互交错。我不确定我能理解这将是怎样的预期效果,因为每个t
延迟回调都会在此处执行完全相同的blit
操作,因此不会有明显的区别。
【讨论】:
并不是说对setTimeout
的调用没有被压入调用堆栈。每个功能都是。当你调用setTimeout
时会发生什么,它推迟了指定函数的执行。因此,setTimeout
和调用函数都会在指定函数执行之前返回。因此调用堆栈在指定函数执行之前被清除。
在我更新代码以包含下次运行的回调之前,这是正确的答案。回调是递归循环函数,所以不能再这样展开了。以上是关于在没有堆栈溢出的情况下在 javascript 中执行无限动画的模式的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在不使用 ImageMagick 或其他第三方软件的情况下在 R 中制作 GIF?
执行堆栈操作以在没有集合api的情况下在java中推送字符串
如何在没有 jQuery 的情况下在 JavaScript 中打开 JSON 文件?
如何在没有jQuery的情况下在javascript中执行php文件