RangeError: Maximum call stack size error in JS function

RangeError: Maximum call stack size error in JS function

  function findRandomDayIndex() {
    var dayindex = _.random(0, 39);
    var slot = dayslots[dayindex]; // array of 40 objects
    if(slot.filled === true || slot === undefined) {
      return findRandomDayIndex();
    } else {
      return dayindex;
    } 
  }

我收到错误:

RangeError: Maximum call stack size exceeded iteration of the same function

函数怎么写比较好?

你不需要递归来做到这一点。通过一些重构,您可以映射数组以保存索引,然后过滤未定义和填充的值,然后从该新数组中获取随机项,例如:

function findRandomDayIndex() {
    var notFilled = dayslots.map(function(value, index) {
        return {
            value: value,
            index: index
        };
    }).filter(function(day) {
        return day.value !== undefined && !day.value.filled;
    });
    if (!notFilled.length) {
        // all items of dayslots are undefined or filled
        // handle this case here
    }
    var dayindex = _.random(0, notFilled.length - 1);
    return notFilled[dayindex].index;
}

你可以试试这个版本

function findRandomDayIndex()
{
   var dayindex = Math.random(0, 39);
   while( ( slot = dayslots[dayindex] ) == null )
       dayindex = Math.random(0, 39);
   return dayindex ;
}

请检查dayslot的一致性,以防止无限循环

这是一个处理所有时段都已满的情况。示例代码 returns -1,但您可以将其更新为 return 任何内容。

function findRandomDayIndex() {
    // Create an array of indexes for items that aren't filled
    var m = _.map(dayslots, function(v, k) {
        if (!v.filled) {
            return k;
        }
    });
    // The array will have undefined for those already filled, so we use lodash without to remove them
    m = _.without(m, undefined);
    if (m.length === 0) {
        // Handle when all slots are filled
        return -1;
    } else {
        // return a random index
        return m[_.random(0, m.length)];
    }
}

// Lets create some test data
var dayslots = [];
for (var i = 0; i < 40; i++) {
    dayslots.push({
        filled: false
    });
}

// Test our function    
console.log(findRandomDayIndex());

如果将 filled 更改为 true,则会得到 -1。

正如@CodeiSir 所评论的那样,因为没有空闲代码进入无限循环。所以我改变了下面的代码并且它工作正常。谢谢!

      if (_.findWhere(dayslots, {filled: false}) !== undefined) {
          var dayindex = _.random(0, 39); 
          var slot = dayslots[dayindex];
          console.log(dayslots.length);
          if(slot.filled === true || slot === undefined) {
            return findRandomDayIndex();
          } else {
            return dayindex;
          } 
        }