jjzjj

JavaScript 递归 : Maximum call stack size exceeded

coder 2024-05-13 原文

我有一个递归函数,可以在 Canvas 上移动一些圆圈。覆盖的圆圈被放大(放大),所有其他圆圈被推开。 插入的圆圈插入其他圆圈等等,直到缩放完成。

我收到错误消息“超出最大调用堆栈大小”,我理解这个问题,但我就是不知道如何解决... 我找到了解决一般递归问题的三种可能的解决方案:

  1. 将递归改为迭代
  2. 使用memoization
  3. 使用 SetTimeout

但我认为我不能使用它们中的任何一个:

  1. 我无法实现迭代,因为所需的操作数未知
  2. 我不太了解内存,但我认为它也不适合(或者我错了,有人可以告诉我不同​​的说法?)
  3. 我不能使用 SetTimeout,因为它应该在这个特定的动画中阻止函数调用。

我该如何解决这个问题?

// Pushes circles aside when some other circle leans on these circles (on zoom in)
var moveCirclesAside = function(circle1, circleToSkip, groupOfMoves) {
    var count = circles.length;
    for (var i = 0; i < count; i++) {

        // Skip the same circle
        if (i == circle1.i) {
            continue;
        }

        // Also skip the circle which was intended not to move any further
        if (circleToSkip != null && i == circleToSkip.i) {
            continue;
        }

        // Get second circle
        var circle2 = circles[i];

        // Calculate a distance between two circles
        var dx = circle2.x - circle1.x;
        var dy = circle2.y - circle1.y;
        var distance = Math.sqrt((dx * dx) + (dy * dy));

        // If circles already collided need to do some moving...
        if (distance <= circle1.r + circle2.r + OD.config.circleSpacing) {

            // Get collision angles
            var angle = Math.atan2(dy, dx);
            var sine = Math.sin(angle);
            var cosine = Math.cos(angle);

            // Some circle position calculation
            var x = OD.config.circleSpacing;
            var xb = x + (circle1.r + circle2.r);
            var yb = dy * cosine - dx * sine;

            // Save each state (move) of any circle to the stack for later rollback of the movement
            groupOfMoves.push(copyCircleByVal(circle2));

            // Move the circle
            circle2.x = circle1.x + (xb * cosine - yb * sine);
            circle2.y = circle1.y + (yb * cosine + xb * sine);

            // Make sure that circle won't go anywhere out of the canvas
            adjustCircleByBoundary(circle2);

            // If moved circle leans against some other circles make sure that they are moved accordingly
            // And such related moves must be grouped for correct rolback of moves later - so we pass 'groupOfMoves' var
            moveCirclesAside(circle2, circle1, groupOfMoves);
        }
    }
};

最佳答案

1) I can not implement iteration because of unknown count of operations needed;

好吧,我没有看过你的代码,但是一般避免线性递归(你这里有一个线性递归)看起来像这样:

while (1 == 1) {
    if (breakcondition)
        break;
    doSomeCode()
}

因此您不必像在 for 循环中那样知道确切的迭代次数。

关于JavaScript 递归 : Maximum call stack size exceeded,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9497625/

有关JavaScript 递归 : Maximum call stack size exceeded的更多相关文章

  1. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  2. ruby - 递归地将所有数字字符串转换为 Ruby 哈希中的整数 - 2

    我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj

  3. Ruby:标准递归模式 - 2

    我经常迷上ruby​​的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情

  4. ruby - 为什么我用递归得到 "stack level too deep"? - 2

    我有这个ruby代码:defget_sumnreturn0ifn似乎正在为999之前的值工作。当我尝试9999时,它给了我这个:stackleveltoodeep(SystemStackError)所以,我添加了这个:RubyVM::InstructionSequence.compile_option={:tailcall_optimization=>true,:trace_instruction=>false}但什么也没发生。我的ruby版本是:ruby1.9.3p392(2013-02-22revision39386)[x86_64-darwin12.2.1]我还增加了机器的堆栈大

  5. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  6. ruby - 构建网络蜘蛛时,应该使用递归吗? - 2

    构建一个深度优先的网络蜘蛛,这意味着它将访问第一页上的所有链接,然后转到每个链接,并访问所有第二页上的链接...你应该使用递归吗?我发现这是CPU密集型的。defrecursion()linkz_on_first_page.eachdo|link|recursion(link)endendrecursion(firstpage) 最佳答案 绝对不是,由于万维网的实际性质,您很快就会遇到问题。当您访问带有主导航部分的网站时,每个页面都链接到其他页面,您就进入了一个无限循环。您可以跟踪您处理了哪些链接,但即便如此,递归循环并不真正适合万

  7. ruby-on-rails - 如何以递归方式将 YAML 文件扁平化为 JSON 对象,其中键是点分隔的字符串? - 2

    例如,如果我有YAML文件en:questions:new:'NewQuestion'other:recent:'Recent'old:'Old'这最终会变成一个json对象,例如{'questions.new':'NewQuestion','questions.other.recent':'Recent','questions.other.old':'Old'} 最佳答案 由于问题是关于在Rails应用程序上使用YAML文件进行i18n,因此值得注意i18ngem提供了一个辅助模块I18n::Backend::Flatten完全像

  8. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  9. ruby-on-rails - 我将 Rails3 与 tinymce 一起使用。如何呈现用户关闭浏览器javascript然后输入xss? - 2

    我有一个用Rails3编写的站点。我的帖子模型有一个名为“内容”的文本列。在帖子面板中,html表单使用tinymce将“content”列设置为textarea字段。在首页,因为使用了tinymce,post.html.erb的代码需要用这样的原始方法来实现。.好的,现在如果我关闭浏览器javascript,这个文本区域可以在没有tinymce的情况下输入,也许用户会输入任何xss,比如alert('xss');.我的前台会显示那个警告框。我尝试sanitize(@post.content)在posts_controller中,但sanitize方法将相互过滤tinymce样式。例如

  10. ruby - 为什么尾递归 gcd 比 rubinius 的 while 循环更快 - 2

    我有这两个gcd函数的实现:defgcd1(a,b)ifa==baelsifa>bif(a%b)==0belsegcd1(a%b,b)endelseif(b%a)==0aelsegcd1(a,b%a)endendenddefgcd2(a,b)if(a==b)returnaelsifb>amin,max=a,belsemin,max=b,aendwhile(max%min)!=0min,max=max%min,minendminend函数gcd1是尾递归的,而gcd2使用while循环。我已经验证rubinius通过对阶乘函数进行基准测试来执行TCO,只有阶乘函数基准测试显示递归版本和迭

随机推荐