首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >当javascript中的递归函数可计数时,最大调用堆栈大小超过RangeError

当javascript中的递归函数可计数时,最大调用堆栈大小超过RangeError
EN

Stack Overflow用户
提问于 2018-06-05 23:43:40
回答 3查看 2.2K关注 0票数 1

我已经创建了一个脚本,用选定的小数位数来除数。除非我设置了大量的小数位,否则一切都很好。通过Node.js运行的文件在十进制数组长度达到~2400时放弃,Chrome在~1900时放弃。

我简化了我的代码,下面的脚本示例将Maximum call stack size exceeded RangeError抛出到~20000十进制数组长度。我认为当循环或递归函数被无休止地调用时,会抛出这个错误,但在我的例子中,迭代的次数是可计数的。这可能是一个很大的数字,但我的模块的目的是对大数字进行数学运算。

为什么会发生这种情况,我可以避免发生这种RangeError吗?

代码语言:javascript
复制
var decimals = [];
var max = 20000;

recurse();

function recurse() {
  decimals.push(Math.floor(Math.random()*10));
  if(decimals.length === max) return;
  recurse();
}

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-06-05 23:48:03

没有,你可以放在调用栈上的函数调用是有限制的,所以即使你的递归函数有一个可达的基本情况,如果递归调用的数量太大,它仍然会抛出错误。

一种解决方法是使用称为trampoline的技术,在这种技术中,您不会直接在函数内部执行递归调用,但insted会返回一个新函数,然后在循环中执行该函数,直到到达基例。

使用这种技术,您的函数可以执行任意数量的递归调用,因为您不会同时将更多的这些函数调用放到调用堆栈中,因此它不会溢出。

代码语言:javascript
复制
var decimals = [];
var max = 20000;

function _recurse(){
  decimals.push(Math.floor(Math.random()*10));
  if(decimals.length === max) return;
  return () => _recurse();
}

const trampoline = fn => (...args) => {
  let res = fn(...args);
  while (typeof res === 'function') { res = res(); }
  return res;
}

const recurse = trampoline(_recurse);

recurse()

console.log(decimals);

请注意,您的问题可以在不使用递归的情况下以一种简单得多的方式解决,即使用循环。例如:

代码语言:javascript
复制
function createRandomSequence(amount) {
  const decimals = [];
  for (let i = 0; i < amount; i++) {
    decimals.push(Math.floor(Math.random()*10));
  }
  return decimals;
}

console.log(createRandomSequence(10));

票数 4
EN

Stack Overflow用户

发布于 2018-06-05 23:57:40

只需使用常规循环,或类似于:

代码语言:javascript
复制
 const random = length => Array.from({ length }, () => Math.floor(Math.random() * 10));

const decimals = random(20000);
票数 3
EN

Stack Overflow用户

发布于 2018-06-06 00:03:50

关于调用堆栈:请参阅this web page

如果你想要的是20,000 (伪随机)小数,你也可以使用类似这样的东西:

代码语言:javascript
复制
var maxDecimals = 20000;
var decimals = Array.from({length: maxDecimals})
  .map(v => Math.floor(Math.random()*10));
  
console.log(decimals);

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50704116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档