Il arrive parfois que l'on ai besoin que plusieurs conditions soient remplies pour executer une instruction finale. Dans le cas où une des conditions n'est pas remplie, les tests suivants ne sont plus nécessaires, et il peut être important de ne pas les tester en terme d'optimisation. Quand ces conditions sont nombreuses, on peut se retrouver avec une grosse imbrication de if ... else, qui en plus de nuire terriblement à la lisisbilité du code, augmentent la complexité de celui-ci (la compléxité d'un code se calcule entre autre avec le nombre d'instructions if imbriquées.

Il est vrai qu'une simplification pourrait consister à utiliser des ET logiques (&&) dans un ordre défini, comme je l'explique dans ce post, mais si certaines conditions doivent être succédées par un traitement, ce système ne fonctionne plus.

Le problème s'est posé à moi pour la nouvelle version de mon moteur de blog, olrs de l'ajout d'un commentaire. En effet, si le nom est vide, je n'ai pas besoin de tester le contenu du commentaire. Si le commentaire est vide, je n'ai pas besoin de tester la valididté de l'email, etc... Si l'une de ces conditions est fausse, l'enregistrement du commentaire ne doit pas se faire. Cette astuce est valable pour tout langage, je vais donc l'illustrer ici en AS2.

Voici donc le code que l'on peut s'attendre à avoir :// Test du nom
if (!this.name.length) {
   trace("Le nom est obligatoire");
} else {
   // Test du commentaire
   if (!this.comment.length) {
      trace("Le commentaire est obligatoire");
   } else {
      // Test de l'adresse email
      if (!this.isValidEmail(this.email)) {
         trace("L'adresse email saisie n'est pas valide");
      } else {
         // Enregistrement du commentaire
         this.saveComment();
      }
   }
}
Evidemment, les moyens de simplifier le code sont nombreux : création d'une variable booleenne spécifiant si une erreur est survenue, stockage du message d'erreur pour n'avoir qu'une instruction trace(), etc... Mais si le code présenté ici est simple, ce n'est pas toujours le cas. Et quoi qu'il arrive, tester si une erreur est déja survenue rajoute un [i]if[/if] à chaque test de condition ... Une solution que j'ai trouvée consiste à utilise l'instruction do ... while conjugée avec break pour arrêter le traitement dés qu'une erreur est trouvée. Cela correspond en fait à un goto, que l'on rencontre dans certains langages:// Message d'erreur eventuel
var err = false;
// Première et dernière boucle
do {
   // Test du nom
   if (!this.name.length) {
      err = "Le nom est obligatoire";
      break;
   }
   // Test du commentaire
   if (!this.comment.length) {
      err = "Le commentaire est obligatoire";
      break;
   }
   // Test du mail
   if (!this.isValidEmail(this.email)) {
      err = "L'adresse email saisie n'est pas valide";
      break;
   }
   // Enregistrement du commentaire
   this.saveComment();
// Le while(false) interromps la boucle dés le premier passage
} while (false);
// S'il y a eu une erreur, on l'affiche
if (err) {
   trace(err);
}

Cet exemple présente une situation assez simple, qui est facilement optimisable d'autres manières. Mais cette utilisation du do...while peut-être bien pratique dans des situations plus complexes ... :)