几个星期前我问了一个关于使用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命令计算这个或另一种方法的解决方案?
谢谢!
答案 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