【问题标题】:Recursion and setTimeout in JavaScriptJavaScript 中的递归和 setTimeout
【发布时间】:2011-04-07 17:00:45
【问题描述】:

我的 JavaScript 文件中有一个递归函数。它看起来像这样:

function process(node){
    if(someCondition)
        return someValue;
    a = process(node.children);
    b = doSomething(a);
    return b;
}

问题是我想在这个递归的每一步将系统的状态显示到 HTML 输出中。每个步骤之间应该有一个延迟。 (假设我想向用户实时显示递归)。在任何其他语言中,我都会在函数内部使用 delay() 调用,但由于 JavaScript 不支持 setTimeout() 之外的任何东西来执行此类操作,因此我迷路了,因为我不知道如何在这个特定的环境中使用 setTimeout 调用案例。

通常在更简单的情况下,我会使用这样的东西:

function process(node){
    if(someCondition)
        return someValue;
    setTimeout("process(node.children)", delay);
}

;但是由于我的原始函数返回一个值,我不知道如何进行。

提前致谢。

【问题讨论】:

  • 您有什么理由要向用户实时显示它吗?如果您愿意解释,也许我们可以改变您的想法或向您提出不同的建议。

标签: javascript recursion timeout settimeout


【解决方案1】:

如果您使用“安全”递归,您可以轻松更新 dom,请参阅https://stackoverflow.com/questions/24208676/how-to-use-recursion-in-javascript/24208677

/*
this will obviously crash... and all recursion is at risk of running out of call stack and breaking your page...

function recursion(c){
    c = c || 0;
    console.log(c++);
    recursion(c);
}
recursion();

*/

// add a setTimeout to reset the call stack and it will run "forever" without breaking your page!
// use chrome's heap snapshot tool to prove it to yourself.  :)

function recursion(c){
    setTimeout(function(c){
        c = c || 0;
        console.log(c++);
        recursion(c);
    },0,c);
}

recursion();

// another approach is to use event handlers, but that ultimately uses more code and more resources

【讨论】:

    【解决方案2】:

    那又怎样?

    var result;
    
    function process(node) {
      if (arguments.length > 1) {
        result = doSomething(result);
        displayResult();
      }
      if (someCondition) {
        result = someValue;
        displayResult();
        return;
      }
      setTimeout(function() {
        process(node.children, true);
      }, delay);
    }
    

    【讨论】:

      【解决方案3】:
      • 将所有调用放入匿名函数中。
      • 将它们放入队列中。
      • 使用递归函数对每个函数应用 0ms setTimeout。

      例子:

      变种队列 = []; queue.push(function(){callYourCodeThatTakesSomeTime('param1','param2','...')}); var defer = 函数(队列){ 如果 (!queue.length) 返回; queue.shift()(); 设置超时(延迟,0,队列); } 延迟(队列);

      【讨论】:

        【解决方案4】:

        我认为这不能作为纯递归算法工作。

        您可以将 b 的当前值存储在全局变量中。

        然后您可以使用 setInterval 以类似的方式处理值,在每次迭代时更新 b 的值,使用 clearTimeout 在满足条件时停止执行。

        【讨论】:

          【解决方案5】:

          如果您的目标是 HTML5,您可以尝试web worker

          【讨论】:

          • 不幸的是,看起来即使是网络工作者也无法解决这个问题。有什么想法吗?
          猜你喜欢
          • 1970-01-01
          • 2011-12-31
          • 2019-07-10
          • 2018-03-11
          • 1970-01-01
          • 2014-06-04
          • 2012-01-31
          • 2019-06-10
          • 1970-01-01
          相关资源
          最近更新 更多