Récurrence JavaScript: taille maximale de la pile d'appels dépassée

J'ai une fonction récursive pour le déplacement de certains cercles sur une toile. Overed cercle est agrandie (zoom avant) et tous les autres cercles est repoussé.
Poussé cercles de pousser les autres cercles et ainsi de suite jusqu'à ce que le zoom est complète.

J'obtiens une erreur "le Maximum de la pile des appels taille dépassé", et je comprends le problème, mais je ne sais pas comment le résoudre...
J'ai trouvé trois solutions possibles pour résoudre les problèmes de la récursivité en général:

  1. Changer la récursivité à l'itération
  2. Utilisation memoization
  3. Utiliser SetTimeout

Mais je pense que je peux utiliser aucun d'entre eux:

  1. Je ne peux pas mettre en œuvre l'itération en raison de inconnu de comptage des opérations nécessaires
  2. Je ne comprends pas memoization assez bien, mais je pense qu'il ne convient d'ailleurs pas (ou peut-être que je me trompe et que quelqu'un pouvait m'a dit différemment?)
  3. Je ne peux pas utiliser SetTimeout, parce qu'il devrait être fonction de blocage des appels à cette animation particulière.

Comment puis-je résoudre ce problème?

//Pushes circles aside when some other circle leans on these circles (on zoom in)
var moveCirclesAside = function(circle1, circleToSkip, groupOfMoves) {
var count = circles.length;
for (var i = 0; i < count; i++) {
//Skip the same circle
if (i == circle1.i) {
continue;
}
//Also skip the circle which was intended not to move any further
if (circleToSkip != null && i == circleToSkip.i) {
continue;
}
//Get second circle
var circle2 = circles[i];
//Calculate a distance between two circles
var dx = circle2.x - circle1.x;
var dy = circle2.y - circle1.y;
var distance = Math.sqrt((dx * dx) + (dy * dy));
//If circles already collided need to do some moving...
if (distance <= circle1.r + circle2.r + OD.config.circleSpacing) {
//Get collision angles
var angle = Math.atan2(dy, dx);
var sine = Math.sin(angle);
var cosine = Math.cos(angle);
//Some circle position calculation
var x = OD.config.circleSpacing;
var xb = x + (circle1.r + circle2.r);
var yb = dy * cosine - dx * sine;
//Save each state (move) of any circle to the stack for later rollback of the movement
groupOfMoves.push(copyCircleByVal(circle2));
//Move the circle
circle2.x = circle1.x + (xb * cosine - yb * sine);
circle2.y = circle1.y + (yb * cosine + xb * sine);
//Make sure that circle won't go anywhere out of the canvas
adjustCircleByBoundary(circle2);
//If moved circle leans against some other circles make sure that they are moved accordingly
//And such related moves must be grouped for correct rolback of moves later - so we pass 'groupOfMoves' var
moveCirclesAside(circle2, circle1, groupOfMoves);
}
}
};

source d'informationauteur fizis | 2012-02-29