2010-10-26 70 views
2

幾周前我提出了一個問題,關於使用setTimeout作爲階乘函數,但不幸的是,這是一個未註冊的帳戶,我從來沒有得到完整的答案。如何在Javascript中使用setTimeout或setInterval編寫階乘函數

我的主要問題是我想編寫一個函數來計算數字的階乘,但使用setTimeout或setInterval命令。這背後的動力是重置IE使用的計數器,以避免長時間運行的腳本警告。目前,階乘函數我是:

function factorial(n) { 
    return 0 === n || 1 === n ? 1 : n * factorial(n - 1) 
} 

在我的其他職務,jsumners還跟我提供那些試圖定期使用的setTimeout計算階乘時代碼:

function factorial(x) { 
executions++; 
    if (x > 1) { 
     if (executions % 20 === 0) { 
      return (function() { 
       var y = x; 
       setTimeout(function(y) { return y*factorial(y-1); }, 1); 
      }); 
     } else { 
     return x*factorial(x-1); 
     } 
    } else { 
    executions = 0; 
     return 1; 
    } 
} 

在上面的代碼,理論上應該使用setTimeout命令執行下一次乘法,當執行次數是20的因子(mod 20)時。不幸的是,代碼不起作用,並且如果試圖計算大於20的數的階乘,那麼結果是NaN。如果數字小於20,那麼答案是正確的。

有沒有人知道解決這個或另一種方法來計算factorial通過使用setTimeout或setInterval命令?

謝謝!

回答

4

這是因爲你指定y作爲參數,這是undefined執行時,因爲它沒有通過,你可以通過改變這個解決它:

setTimeout(function(y) { return y*factorial(y-1); }, 1); 

要這樣:

setTimeout(function() { return y*factorial(y-1); }, 1); 

但是,它仍然是NaN,因爲這裏:

 return (function() { 
      var y = x; 
      setTimeout(function() { return y*factorial(y-1); }, 1); 
     }); 

您仍然要返回函數,而不是可以相乘的數字,所以您仍然不能以這種方式使用setTimeout()。你可以傳遞一個回調,當所有事情都完成時執行,但你不能讓它遞歸併返回給這樣的調用者。

+0

感謝打破代碼對我來說,讓我知道問題是什麼。這就是說,我應該說我是Javascript的業餘愛好者,所以我不太清楚如何按照您的建議實施回調。我擺脫了'返回'的語法,而只是有setTimeout命令,然後一旦乘數下降到1我然後調用回調返回答案?再次感謝您的幫助。 – Josiah 2010-10-26 01:48:59

0

回調風格的階乘並計劃與setTimeout的每一步反覆發作是:

// private helper function (recurrency with accumulation) 
function _factorial(acc, n, callback){ 
    if(n==0){ 
    callback(acc); 
    }else{ 
    var callback_wrapper = function(result){ 
     callback(result); 
    }; 
    setTimeout(function(){_factorial(acc * n, n-1, callback_wrapper)}, 10); 
    } 
} 

// public function 
function factorial(n, callback){ 
    _factorial(1, n, callback); 
} 

// usage example 
factorial(10, function(result){console.log(result)}); 

- 乾杯, Lambder

http://lambder.com/

http://vanadiumJS.com/