2010-09-03 40 views
1

我在JavaScript文件中有一個遞歸函數。它看起來是這樣的:JavaScript中的遞歸和setTimeout

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

,但因爲我原來的函數返回一個值,我不知道如何着手。

在此先感謝。

+1

有你想要顯示它活到用戶的任何原因?如果你能解釋一下,也許我們可以改變主意或者向你提出一些不同的建議。 – Alex 2010-09-04 02:40:40

回答

1

我認爲這不會作爲一個純粹的遞歸算法。

您可以將b的當前值存儲在全局變量中。

然後,您可以使用setInterval以類似的方式處理該值,在每次迭代時更新b的值,使用clearTimeout在條件滿足時停止執行。

0

如果你的目標是HTML5,你可以試試web worker

+0

不幸的是,即使網絡工作者似乎也無法解決這個問題。有任何想法嗎? – Niyaz 2010-09-03 12:30:59

1
  • 將所有調用放入匿名函數中。
  • 將它們放入隊列中。
  • 使用遞歸函數在每個函數上應用0ms setTimeout。

例子:

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

怎麼樣?

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); 
} 
0

,如果你用「安全」遞歸您可以輕鬆地更新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