【问题标题】:Maximum call stack size exceeded with Javascript Canvas animationJavascript Canvas 动画超出了最大调用堆栈大小
【发布时间】:2014-06-14 21:25:05
【问题描述】:

我有一个我一直在搞乱的 jsFiddle,试图让我的小游戏通过类等变得更有条理,但是当我请求动画帧时,传入对象(每个帧都有一些功能每个对象),我得到一个最大调用堆栈大小错误。如何在不放弃课程的情况下解决此问题?

jsFiddle: http://jsfiddle.net/Blawkbuilder/Q5U3X/109/

我怀疑是罪魁祸首的台词:

    window.requestAnimationFrame(draw(p1,p2));

但控制台链接到的行出现在 jquery 的某处:

    } else if ( !rhtml.test( elem ) ) {

修复?我对 javascript 有点陌生。

(如果需要,这里是以前的,不是基于类的版本,它仍然可以按照我想要的方式运行) http://jsfiddle.net/Blawkbuilder/9hmca/131/

【问题讨论】:

  • 嗯,您的第一个问题是requestAnimationFrame 将函数作为参数,但您传入的是调用 函数的结果。让我看看这是否是整个问题。
  • 正如 Intredasting 所说,您没有将draw 作为requestAnimationFrame 的回调传递,但您直接调用它并且因为这条线在draw 本身内部,所以您有一个无休止的递归调用,导致给定的错误。
  • 是的,这绝对是整个问题。我会添加它作为答案。

标签: javascript jquery animation canvas requestanimationframe


【解决方案1】:

requestAnimationFrame 接受回调。您正在评估draw(p1, p2) 并将其返回值传递给requestAnimationFrame。你应该改成这样:

requestAnimationFrame(function() { draw(p1, p2); });

这类似于 setInterval/setTimeout。

【讨论】:

  • 我会支持你的评论,但我还没有 15 个代表。
【解决方案2】:

requestAnimationFrame 将不带参数的回调函数作为参数。你得到堆栈溢出的原因是你提供了参数draw(p1, p2)(而不是draw),它实际上调用draw函数,然后犯了同样的错误调用draw 函数...(等等)。您在第二个 jsFiddle 中做得正确。

要解决这个问题,您需要 draw 不接受任何参数。或者,创建一个不带任何参数的“包装器”函数,它本身只是使用适当的参数调用 draw。正如另一个答案所暗示的那样,最简单的方法是像requestAnimationFrame(function() {draw(p1, p2); }) 那样做。

顺便说一句,告诉你这是比喻给你一条鱼,而不是教你如何钓鱼。要真正理解这一点,您需要更多地了解函数式编程,这可能会变得有点抽象。在此示例中,请了解函数只不过是具有“可调用”(或“可调用”)特殊属性的对象。 requestAnimationFrame 是一个函数,其第一个参数 callback 是另一个函数。换句话说,requestAnimationFrame 期望 callback 是可调用的。但是你给它的是调用函数的result,而不是函数本身。

function() {draw(p1, p2);} 起作用的原因是function() { ... } 语法构造了一个匿名 函数——一个没有名称的函数,但仍然是一个可以调用的函数。

【讨论】:

  • 您应该始终保持全局变量的数量最少。只要有可能,您应该将所有变量定义封装到 private 范围内。
  • 问题是我想将我的动作从绘图循环外部化(如果是这样的话)并进入“播放器”的类 - 这需要我将播放器作为参数传递.
  • 是的,我将编辑答案以不建议全局变量。在 JS 中,由于作用域和性能原因,全局变量是不好的。
  • 不管怎样,它奏效了。 (我很想赞成你的回答,但我仍然是 5 代表)
猜你喜欢
  • 1970-01-01
  • 2013-08-23
  • 2019-05-21
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 2012-06-26
  • 2017-07-02
  • 2020-11-19
相关资源
最近更新 更多