如何使用setTimeout或setInterval在Javascript中编写阶乘函数

时间:2010-10-26 00:13:19

标签: javascript internet-explorer settimeout setinterval

几个星期前我问了一个关于使用setTimeout进行阶乘函数的问题,但不幸的是,它有一个未注册的帐户,我从来没有得到完整的答案。

我的主要问题是我想编写一个计算数字阶乘但使用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,那么答案是正确的。

有没有人知道使用setTimeout或setInterval命令计算这个或另一种方法的解决方案?

谢谢!

2 个答案:

答案 0 :(得分: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()。你可以传递一个在完成所有事情后执行的回调,但你不能让它递归并返回给这样的调用者。

答案 1 :(得分: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/