代码之家  ›  专栏  ›  技术社区  ›  Niyaz

javascript中的递归和设置超时

  •  1
  • Niyaz  · 技术社区  · 14 年前

    我的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);
    }
    

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

    事先谢谢。

    5 回复  |  直到 11 年前
        1
  •  1
  •   Matt    14 年前

    我认为这不能作为一个纯粹的递归算法工作。

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

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

        2
  •  1
  •   c0rnh0li0    14 年前
    • 将所有调用放入匿名函数。
    • 把他们排成一队。
    • 使用递归函数对每个函数应用0毫秒设置超时。

    例子:

    var queue = [];
    queue.push(function(){callYourCodeThatTakesSomeTime('param1','param2','...')});
    var defer = function(queue){
        if (!queue.length)
            return;
        queue.shift()();
        setTimeout(defer, 0, queue);
    }
    defer(queue);
    
        3
  •  0
  •   Seth    14 年前

    你可以试试 web worker 如果你的目标是HTML5。

        4
  •  0
  •   gtournie    12 年前

    那怎么办?

    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);
    }
    
        5
  •  0
  •   Community CDub    8 年前

    如果使用“安全”递归,则可以轻松更新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