Programación multihilos (threads) en Javascript

Documento sin título
Programación multihilos (threads) en Javascript
Muchas veces cuando necesitamos ejecutar diferentes procesos de javascript en el navegador, tenemos la dificultad de no poder hacerlo ya que cuando ejecutamos un ciclo while (por ejemplo), se bloquea el navegador. Buscando por la red he encontrado una librería (esta disponible en http://sourceforge.net/projects/jsthread/ ) que simula la ejecución de varios procesos o threads al "mismo tiempo".
Aqui un ejemplo:
<script type="text/javascript">
 function proceso(){
  while(true){
   document.writeln("Hola mundo");
  }
 }
</script>
En este ejemplo simplemente se ejecuta el proceso y bloquea el navegador.
Ahora miremos como seria con la librería.
<script type="text/javascript" src="Concurrent.Thread.js"></script>
<script type="text/javascript">
  function proceso(){
   while(true){
    document.writeln("Hola mundo");
   }
  }

Concurrent.Thread.create(proceso);
</script>
Explicación:
1. Primero incluiremos la ruta de la librería con <script type="text/javascript" src="Concurrent.Thread.js"></script>.
2. Luego escribimos nuestro proceso.
 function proceso(){
   while(true){
    document.writeln("Hola mundo");
   }
  }
3. Ahora incluimos la creación del thread en el momento que necesitemos ejecutar el proceso, en este caso lo iniciare al momento de cargar la página.
Concurrent.Thread.create(proceso);
El parámetro "proceso", es la función que se ejecutará en modo paralelo.

Esta librería también nos permite crear un thread que reciba parámetros.
<script type="text/javascript" src="Concurrent.Thread.js"></script>
<script type="text/javascript">
  function proceso(param){
   while(true){
    document.writeln(param);
   }
  }

Concurrent.Thread.create(proceso,"Hola mundo");
</script>
En la línea Concurrent.Thread.create(proceso,"Hola mundo"); se agrega el parámetro que recibe la función. Si agregáramos otra función que reciba mas parámetros, se debe agregar los demás parámetros separados por comas.
Concurrent.Thread.create(proceso,param1, param2, .. paramx);
Bueno, ahora parásemos a un ejemplo un poco mas complicado.
Lo que hace este código es dibujar una serie de cuadros coloreados y moviendo sen, mostrando la posición en la que se encuentran.
Para este ejemplo se utilizo JQUERY para facilitar el renderizado de los cuadros.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Multihilos JS</title>
    <script type="text/javascript" src="Concurrent.Thread.js"></script>
    <script type="text/javascript" src="jquery.js" charset="utf-8"></script>
    <script type="text/javascript">
     var limDivTrab_left=700;
     var limDivTrab_top=600;
   
     var limDivTrab_leftMIN=10;
     var limDivTrab_topMIN=10;
   
   
     function rebotar_cuadro (id, left_inicial, top_inicial, color, _direccion){
      var incLeft=left_inicial;
      var incTop=top_inicial;
      var direccion=_direccion; //1: incLeft+ , incTop -
              //2: incLeft+ , incTop +
                                     //3: incLeft- , incTop +
                                     //4: incLeft- , incTop - 
      $('body').append("<div style='cursor:pointer' id='cuadro"+id+"'></div>");
    
      var cuadro= $('#cuadro'+id);
    
      cuadro.addClass("class_cuadro").css({
       position: "absolute",
       left: left_inicial + "px",
       top: top_inicial + "px",
       backgroundColor: color 
      });
   
      cuadro.html("<strong><span class='texto_inf_pos' id='CuadroLeftTop" + id + "'></strong></span><span class=\"cuadro\">Cuadro" + id + "</span>");
      var CuadroLeftTop= $('#CuadroLeftTop'+id);   
    
    while ( 1 ) {
       var position = cuadro.position();
       CuadroLeftTop.html("Left : " + position.left + "px, top : " + position.top + "px<br>"); 
   
       //Definir la direccion del cuadro 
       if(direccion==1){
        incLeft++;
        incTop--; 
    
        if(position.top<limDivTrab_topMIN){
         direccion=2;
        }else if(position.left>=limDivTrab_left){
         direccion=4;
        } 
       }else if(direccion==2){
        incLeft++;
        incTop ++;
    
        if(position.left>=limDivTrab_left){
         direccion=3; 
        }else if(position.top>=limDivTrab_top){
         direccion=1;
        } 
       }else if(direccion==3){
        incLeft--;
        incTop ++;
    
        if(position.top>=limDivTrab_top){
         direccion=4;
        }else if(position.left<limDivTrab_leftMIN){
         direccion=2;
        } 
       }else if(direccion==4){
        incLeft--;
        incTop --;
    
        if(position.left<limDivTrab_leftMIN){
         direccion=1;
        }else if(position.top<limDivTrab_topMIN){
         direccion=3;
        }
       } 
   
       cuadro.css({left: incLeft + "px",top: incTop + "px"}); 
       Concurrent.Thread.sleep(30); 
      } 
     }
   
     Concurrent.Thread.create(rebotar_cuadro, "1",1,4,"#009",1); 
     Concurrent.Thread.create(rebotar_cuadro, "2",200,200,"#F00",2);
     Concurrent.Thread.create(rebotar_cuadro, "3",100,100,"#0C0",1);
     Concurrent.Thread.create(rebotar_cuadro, "4",335,334,"#999",4);
     Concurrent.Thread.create(rebotar_cuadro, "5",55,444,"#44F",3);
     Concurrent.Thread.create(rebotar_cuadro, "6",86,554,"#23C",2);
   
   </script>

   <style type="text/css">
    .cuadro { 
     height: 100px;
     width: 100px;
     color:#FFF;
    }
   .texto_inf_pos {
     color:#FFF;
     font-style:italic; 
     font-family:Verdana, Geneva, sans-serif;
     font-size:9px;
    }
    .divF{
     border:2px solid #0099FF;
     color:#000000;
     width:815px;
     height:624px;
    }
  </style>
  </head>
  <body>
    <div class="divF"></div>
  </body>
</html> 
 

En el segmento de código, que crea los procesos, nótese que los parámetros de los cuadros son diferentes.
Concurrent.Thread.create(rebotar_cuadro, "1",1,4,"#009",1);
Concurrent.Thread.create(rebotar_cuadro, "2",200,200,"#F00",2);
Concurrent.Thread.create(rebotar_cuadro, "3",100,100,"#0C0",1);
Concurrent.Thread.create(rebotar_cuadro, "4",335,334,"#999",4);
Concurrent.Thread.create(rebotar_cuadro, "5",55,444,"#44F",3);
Concurrent.Thread.create(rebotar_cuadro, "6",86,554,"#23C",2);
Descargar Fuentes del Ejemplo

Comentarios

Entradas más populares de este blog

Listar todos los archivos y carpetas de una ruta especifica en NODEJS

Recorrer campos de un formulario con JQuery

Agregar datos a una tabla desde una fuente externa con JQUERY