简体   繁体   中英

Javascript maximum call stack

Hi everyone I created two functions for my music playlist,

  • one that goes to the next music
  • one passing to a random music

I am aware that my code is not as clean and functional as possible but it works pretty good,

Only an error occurs when i click next until the last music 6 times in my example but then when I click on random, an error Uncaught RangeError: Maximum call stack size exceeded appears , without knowing why, here is my code:

Test

var array = {
   0: {
    "id" : 1,
       "nom" : "Musique 1",
       "durée" : "3m34"
   },
   1: {
    "id" : 2,
       "nom" : "Musique 2",
       "durée" : "2m32"
   },
   2: {
        "id" : 3,
       "nom" : "Musique 3",
          "durée" : "3m54"
   },
   3: {
    "id" : 4,
       "nom" : "Musique 4",
       "durée" : "2m19"
   },
   4: {
    "id" : 5,
       "nom" : "Musique 5",
       "durée" : "2m24"
   },
   5: {
    "id" : 6,
       "nom" : "Musique 6",
       "durée" : "1m58"
   }
};
var count = getObjectLength(array), itmsl = [], mus = -1;

function aleatoire(p){
      var item = Math.floor(Math.random()*count);
      mus = item;
      if(itmsl.indexOf(item) < 0){
        itmsl.push(item);
        echo(array[item]);             
      }else{
        aleatoire();               
      }
      if(itmsl.length >= count){
        itmsl = [];
      }
}
function suivant(){
    mus++;
    if(itmsl.indexOf(mus) < 0 && typeof array[mus] !== 'undefined'){
      itmsl.push(mus);
      echo(array[mus]);
    }else{
      mus = -1;
      itmsl = [];
      suivant();
    }
}
function echo(str){
    if(typeof str != "undefined"){
        console.log(str);
    }else console.log('error');
}

function getObjectLength(obj){
    var length = 0;
    for ( var p in obj ){
      if ( obj.hasOwnProperty( p ) ){
        length++;
      }
    }
  return length;
}

Thank's for the help

The function suivant() neither accepts arguments nor does it return a value. It therefore seems to me that it's uselessly recursive (the whole point of recursion is to use the call stack to manage your data storage but you seem to already manage it manually using an array). The only reason it's written the way it is seems to be to emulate a goto .

Therefore it's very trivial to change it to a while loop (which is of course just another form of goto):

function suivant(){
    var end = 0;

    while (!end) {
        mus++;
        if(itmsl.indexOf(mus) < 0 && typeof array[mus] !== 'undefined'){
            end = 1;
            itmsl.push(mus);
            echo(array[mus]);
        }else{
            mus = -1;
            itmsl = [];
        }
    }
}

Similarly, the function aleatoire should also be iterative:

function aleatoire(){
    var end = 0;

    while (!end) {
        var item = Math.floor(Math.random()*count);
        mus = item;
        if(itmsl.indexOf(item) < 0){
            end = 1;
            itmsl.push(item);
            echo(array[item]);             
        } else {
            // don't end
        }
        if(itmsl.length >= count){
            itmsl = [];
        }
    }
}

If you move your recursion breaker to the top, it should work ie . in your aleatoire method move this code to the top . You don't really need recursion at all once you do that and can safely comment out the else

 function aleatoire(){
          if(itmsl.length >= count){
            itmsl = [];
          }
          var item = Math.floor(Math.random()*count);
          mus = item;
          if(itmsl.indexOf(item) < 0){
            itmsl.push(item);
            echo(array[item]);             
          }
//else{
       //     aleatoire();               
        //  }

    }

The same can be applied to the suviant method too .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM