2010-10-26 77 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/