Foros del Web » Programando para Internet » Javascript »

aporte: programacion secuencial

Estas en el tema de aporte: programacion secuencial en el foro de Javascript en Foros del Web. Hola que hay. Hace mucho que no hago un aporte, y hace nada se me planteaban dos cuestiones al programar en javascript. La primera era ...
  #1 (permalink)  
Antiguo 08/10/2006, 16:36
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
aporte: programacion secuencial

Hola que hay.

Hace mucho que no hago un aporte, y hace nada se me planteaban dos cuestiones al programar en javascript.

La primera era en hacer un setTimeout dentro de una funcion dentro de un objeto.

Es decir, imaginemos que tenemos la funcion que crea los objetos coxe. A esa clase le queremos implementar un metodo, el metodo frenar(), que irá paulatinamente frenando el coxe hasta que su velocidad sea cero. Es decir, si la velocidad>0 entonces velocidad--, y un setTimeout a frenar() en 100ms.

El caso es como escribir eso, porque

Código PHP:
function coxe() {
    
this.velocidad=50;
    
this.frenar=function() {
        if(
this.velocidad>0) {
            
this.velocidad--;
            
setTimeout("this.frenar()"100);
        }
    }

no funciona. Sí que funciona para la primera ejecucion de frenar(), pero al de 100ms llamara a "this.frenar()" literalmente, sin estar this definido.
Para ello recurrimos a las variables globales, y como se nos podrian superponer varios coxes en las variables globales, lo que he hecho es hacer un array y almacenar ahi el coxe (creo una variable serial aleatoriamente, indice del elemento dentro del array, y compruebo que no superpongo nada):

Código PHP:
var coxes=new Array();
function 
coxe() {
    
//crear serial para guardar el objeto globalmente
    
do {
        
this.serial=parseInt(Math.random()*1000);
    } while(
coxes[this.serial]!=undefined);
    
coxes[this.serial]=this;
    
this.velocidad=50;
    
this.frenar=function() {
        if(
this.velocidad>0) {
            
this.velocidad--;
            
setTimeout("coxes["+this.serial+"].frenar()"100);
        }
    }

Y asi no habra problema.





El otro dilema que se me planteaba era de cuestion mas compleja. Lo que queria hacer por ejemplo era frenar el coxe; luego acelerarlo hasta una velocidad concreta (una vez frenado) y cuando acabe de acelerar, esperar 5 segundos por ejemplo y frenarlo de nuevo.


Para resolverlo he creado variables de estado dentro de cada objeto, es decir; consultando una variable del objeto coxe llamada estoyParado, sabre si el coxe en cuestion tiene velocidad 0. Solo hay que comprobar si esa variable es true en todo momento, y cuando sea true, el coxe habra frenado por completo.

De ello se encarga genericamente la funcion comprobarSi. comprobarSi mira a ver si cierta variable tiene ese valor cada 100ms, y cuando adopta ese valor ejecuta la funcion que le pasemos por argumento con los argumentos que tambien le pasemos por argumento (esta es la parte que peor me ha quedado, y deberia hacer un par de retoques).


comprobarSi tambien posee un argumento llamado orden, y el script tiene una variable global llamada ordenGlobal, que permite discernir entre la primera frenada que ejecutemos y la segunda, ya que la variable estoyParado adoptara un valor true siempre que el coxe llegue a 0km/h, y eso puede que ocurra varias veces en nuestro script.


Sin mas, dejo el script en cuestion:
Código PHP:
<html>

<
head>
<
title>Programacion hilada JS</title>
</
head>

<
body>

<
input type="text" size="10" id="laCaja" />

<
script>

var 
ordenGlobal=0;
function 
comprobarSi(orden,nomVar,valor,despues,args) {
    try {
        if( eval(
nomVar)!=valor || ordenGlobal+1!=orden) {
            
//document.body.appendChild( document.createTextNode(nomVar+"="+eval(nomVar)+"\t" ) );
            
setTimeout("comprobarSi("+orden+",'"+nomVar+"',"+valor+", '"+despues+"', '"+args+"')"100);
        }
        else {
            
ordenGlobal=orden;
            
args=eval(args);
            if(
args==undefinedargs=[];
            
//ponemos los argumentos bien: numeros, boleanos y strings (arrays no)
            
var cadena="";
            for(
a=0;a<args.length;a++) {
                if(
typeof args[a]=="string")
                    
cadena+="'"+args[a]+"',";
                else
                    
cadena+=args[a]+",";
            }
            
cadena=cadena.substring(0,cadena.length-1);
            eval(
despues+"("+cadena+")");
        }
    } catch(
e) {    //no estaba definida la variable nomVar aun, seguir probando
        
setTimeout("comprobarSi("+orden+",'"+nomVar+"',"+valor+", '"+despues+"', '"+args+"')"100);
    }
}

var 
coxes=new Array();
function 
coxe() {
    
//crear serial para guardar el objeto globalmente
    
do {
        
this.serial=parseInt(Math.random()*1000);
    } while(
coxes[this.serial]!=undefined);
    
coxes[this.serial]=this;
    
this.velocidad=50;
    
this.estoyParado=!(this.velocidad>0);
    
this.velCte=true;
    
this.frenar=function() {
        if(
this.velocidad>0) {
            
this.velCte=false;
            
this.velocidad--;
            
document.getElementById("laCaja").value=this.velocidad;
            
setTimeout("coxes["+this.serial+"].frenar()"100);
        }
        else {
            
this.estoyParado=true;
            
this.velCte=true;
        }
    }
    
this.acelerar=function(hasta) {
        
this.estoyParado=false;
        
this.velCte=false;
        if(
this.velocidad<hasta) {
            
this.velocidad++;
            
document.getElementById("laCaja").value=this.velocidad;
            
setTimeout("coxes["+this.serial+"].acelerar("+hasta+")"100);
        }
        else {
            
this.velCte=true;
        }
    }
}

var 
sleeps=new Array();
function 
sleep(sgs) {
    
this.terminado=false;
    
//crear serial para guardar el objeto globalmente
    
do {
        
this.serial=parseInt(Math.random()*1000);
    } while(
sleeps[this.serial]!=undefined);
    
sleeps[this.serial]=this;
    
setTimeout("sleeps["+this.serial+"].terminado=true"sgs*1000);
}


var 
miCoxe=new coxe();
miCoxe.frenar();
var 
espera1;
comprobarSi(1,"miCoxe.estoyParado",true"miCoxe.acelerar"'[20]' );
comprobarSi(2,"miCoxe.velCte",true"espera1=new sleep""[5]");
comprobarSi(3,"espera1.terminado",true"miCoxe.frenar");
comprobarSi(4,"miCoxe.estoyParado",true"miCoxe.acelerar"'[50]' );
comprobarSi(5,"miCoxe.velCte",true"fin");
function 
fin() {
    
alert("FIN");
}



</script>


</body>

</html> 

El coxe miCoxe se crea a 50km/h, despues se le da la orden de frenar. Una vez frenado acelerará hasta 20km/h, esperara 5 segundos antes de volver a frenar y por ultimo retomara los 50km/h iniciales. Saltará la funcion fin() cuando todo haya terminado.





No es que sea demasiado practico este script, pero me ha roto un poco la limitacion del lenguaje en cuanto a estas cosas de los threads, y la funcion sleep.


Espero que os parezca interesante.
Saludos a todos
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #2 (permalink)  
Antiguo 09/10/2006, 02:35
Avatar de el_javi  
Fecha de Ingreso: marzo-2005
Ubicación: MAdrid
Mensajes: 844
Antigüedad: 19 años, 1 mes
Puntos: 10
Buenos días derkenuke

Te comento una cosa, y a ver que opinas...

Con el setTimeOut, te da un error, de que el objeto no está definido (me refiero en esto)
Código PHP:
function coxe() {
    
this.velocidad=50;
    
this.frenar=function() {
        if(
this.velocidad>0) {
            
this.velocidad--;
            
setTimeout("this.frenar()"100);
        }
    }

eso, puedes solventarlo con esto:
Código PHP:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<
html>
<
head>
    <
title>Untitled</title>
    <
script language="JavaScript1.2" type="text/javascript">
        function 
coche_object ()
        {
            
this.velocidad 50;
            
this.timeOut null;
            
            
this.frena = function ()
            {
                if(
coche.velocidad 0)
                {
                    
coche.velocidad--;
                    
coche.timeOut setTimeout("coche.frena()"100);
                }
                else
                {
                    if (
coche.velocidad == 0)
                    {
                        
alert ("Hemos frenado del todo");
                        
clearInterval(coche.timeOut);
                    }
                }
            }
        }
        var 
coche = new coche_object ();
    
</script>
</head>

<body>
<a href="javascript:coche.frena()">Pulsame</a>


</body>
</html> 
Defines el Objeto antes de usarlo, como si usaras una clase, pero sin ser una clase en su esencia real.

Espero que esto te pueda ser útil, y me des una opinión de si orientarlo de esa manera...

Un saludo, y a ver que opinas.

  #3 (permalink)  
Antiguo 09/10/2006, 13:02
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Sorry pero..

Lo siento, pero tu idea no me vale porque sólo es válida para un único objeto de la clase coche_object, en concreto el objeto llamado coche. ¿Cómo harías esto?


Código PHP:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<
html>
<
head>
    <
title>Untitled</title>
    <
script language="JavaScript1.2" type="text/javascript">
        function 
coche_object (vel)
        {
            
this.velocidad vel;
            
this.timeOut null;
            
            
this.frena = function ()
            {
                if(
coche.velocidad 0)
                {
                    
coche.velocidad--;
                    
setTimeout("coche.frena()"100);
                }
                else
                {
                    if (
coche.velocidad == 0)
                    {
                        
alert ("Hemos frenado del todo");
                    }
                }
                
document.getElementById("laCaja").value=this.velocidad;
            }
        }
        var 
coche = new coche_object (50);
        var 
coche2=new coche_object(30);
    
</script>
</head>

<body>
<a href="javascript:coche2.frena()">Pulsame</a>
<input type="text" id="laCaja" />

</body>
</html> 
No puedes frenar el coche2 salvo en la primera unidad porque el timeout llama al método del objeto coche, no de coche2. No es una funcion generica, es solamente para el objeto coche

Si te fijas en mi ejemplo se puede hacer con varios objetos independientemente de su nombre; te despreocupas. La idea sigue siendo poner el objeto en una variable global.

Por cierto la linea de
Código PHP:
clearInterval(coche.timeOut); 
la he quitado porque un timeout no se puede cortar con un clearInterval, un timeout sólo ejecuta la funcion una vez, y un interval la ejecuta indefinidamente.


saludos y gracias por responder.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #4 (permalink)  
Antiguo 04/09/2008, 13:47
Avatar de el_javi  
Fecha de Ingreso: marzo-2005
Ubicación: MAdrid
Mensajes: 844
Antigüedad: 19 años, 1 mes
Puntos: 10
Respuesta: aporte: programacion secuencial

Hola juliorjulior

Comenta cuales son los problemas que tienes con los 3 SetTimeOuts y vemos a ver qué podemos hacer, ¿ok?

Saludos

Javier
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 19:28.