2

几周前我问了一个关于将 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;
   }
}

在上面的代码中,理论上应该在执行次数为 20 倍(mod 20)时使用 setTimeout 命令执行下一次乘法。不幸的是,代码不起作用,如果尝试计算大于 20 的数字的阶乘,则结果为 NaN。如果数字小于 20,则答案是正确的。

有谁知道通过使用 setTimeout 或 setInterval 命令来计算阶乘的解决方案或其他方法?

谢谢!

4

2 回答 2

4

这是因为您将其指定yundefined执行时的参数,因为它没有传入,您可以通过更改它来修复它:

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

你仍然返回一个function,而不是一个可以相乘的数字,所以你仍然不能setTimeout()以这种方式使用 a 。您可以传递一个在一切完成后执行的回调,但您不能让它递归并返回给这样的调用者。

于 2010-10-26T00:16:53.227 回答
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)});

——干杯,兰伯德

http://lambder.com/

http://vanadiumJS.com/

于 2011-01-11T11:24:00.710 回答