function asyncWhile(thisArg, testfunc, traitement, callback){
  if (testfunc.call(thisArg)){
    traitement.call(thisArg, function(){
        asyncWhile(thisArg, testfunc, traitement, callback);
      }
    );
  } else {
    callback.call(thisArg);
  }
}

/******************************
 * Exemple
 * ****************************/
/*
echo = function(msg) {
  var m = document.createElement('DIV');
  m.innerHTML = msg;
  document.body.appendChild( m );
};

$(document).ready(function(){
    
    function objTab(tab){
      this.trucs = tab;
    }

    objTab.prototype.showVals = function(){
      var i = 0;
      while(i < this.trucs.length){
        var elem = this.trucs[i];
        if (elem instanceof objTab){
          echo("----->");
          elem.showVals();
          echo("<-----");
        }
        else {
          echo(elem);
        }
        i++;
      }
    };

    objTab.prototype.showValsAsync = function(callback){
      var i = 0;
      asyncWhile(
        this,
        function(){ return i < this.trucs.length;},
        function(callback){
          var elem = this.trucs[i];
          if (! (elem instanceof objTab)){
            echo(elem);
            i++;
            callback();
          }
          else {
            echo("----->");
            elem.showValsAsync(function(){
                echo("<-----");
                i++;
                callback();
              });
          }
        },
        function(){
          callback();
        }
      );
    };

    var chiffres = new objTab([1, 2, 3]);
    var collection = new objTab([7, chiffres, 0, "r"]);

    echo("<H2>WHILE classique</H2>");
    collection.showVals();
    echo("while classique terminé");

    echo("<H2>WHILE asynchrone</H2>");
    collection.showValsAsync(function(){
        echo("while asynchrone terminé");
      });
  });
*/
