Foros del Web » Programando para Internet » Javascript »

como controlar la ejecucion...

Estas en el tema de como controlar la ejecucion... en el foro de Javascript en Foros del Web. qe tal, tego una fiuncion de ajax que ejecuta un for, y dentro de un for mando a llamr otra funcion de ajax que me ...
  #1 (permalink)  
Antiguo 04/10/2007, 16:23
 
Fecha de Ingreso: septiembre-2005
Mensajes: 1.289
Antigüedad: 19 años, 2 meses
Puntos: 3
Pregunta como controlar la ejecucion...

qe tal, tego una fiuncion de ajax que ejecuta un for, y dentro de un for mando a llamr otra funcion de ajax que me geenraun valor que necsito, entonces la funcion donde esta el for se ejecuta mas rapido que la funcion que mando a llmar y no alcanzo a tomar el valro que requiero, me di cuenta por que con un alert que pongo si me lo permite, entonces quisiera saber si es posible hacer que una funcion no continue hasta que otra termine de ejecutarse, de antemano muchas gracias!
__________________
Wow! No se que decir...
  #2 (permalink)  
Antiguo 05/10/2007, 09:10
 
Fecha de Ingreso: septiembre-2005
Mensajes: 1.289
Antigüedad: 19 años, 2 meses
Puntos: 3
Re: como controlar la ejecucion...

no hya alguna idea? :(
__________________
Wow! No se que decir...
  #3 (permalink)  
Antiguo 05/10/2007, 19:17
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 1 mes
Puntos: 45
Re: como controlar la ejecucion...

Tema complicado zyon, tema complicado.

Quizás con algún truco tipo...

Código PHP:
// escribir en el documento una ristra (x)html fuera de tiempo de ejecución.
function e(q,sinBR) {
    var 
elDIV document.createElement("DIV");
    if(
q==undefinedq="";
    if(!
sinBRq+="<br/>";
    
elDIV.innerHTML q;
    for(var 
a=0elDIV.childNodes.length>aa++) {
        
document.body.appendChildelDIV.childNodes[a].cloneNode(true) );
    }
}

var 
finDeTardona falsecomprobador;
function 
tardona() {
    
e("Entro en tardona");
    
// .... cosas que tardan
    // el setTimeout es sólo para simular que la ejecución de tardona() tarda 5 sgs
    
setTimeout( function() {
        
finDeTardona true;
        
e("finDeTardona = true");
    } , 
5000);
}

function 
segundona() {
    
e("Entro en segundona!");
}

function 
principal() {
    
tardona();
    
// Sólo y sólo cuando acabe tardona (finDeTardona = true) ejecutaremos la segundona
    // Comprobaremos si finDeTardona = true cada medio segundo, para ver si podemos lanzar la segundona
    
comprobador setInterval( function() {
        
e("Comprobando: finDeTardona es "+finDeTardona);
        if( 
finDeTardona == true ) {
            
finDeTardona false;            // reestablecemos
            
clearTimeoutcomprobador );    // paramos de comprobar
            
segundona();
        }
    }, 
500);
}

window.onload principal
Claro, que se podría hacer de una manera más global para llamar a cualquier función después de ejecutarla... pero supongo que llevaría más tiempo y más mente abstracta para implementarlo, depende cuales sean tus necesidades finales.


Un saludo.
__________________
- 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 05/10/2007, 19:34
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 1 mes
Puntos: 45
Re: como controlar la ejecucion...

Oye, que me comía la curiosidad y lo he hecho más global, pudiendo hilvanar varias funciones sin problemas, gracias al prototipado:

Código PHP:
// escribir en el documento una ristra (x)html fuera de tiempo de ejecución.
function e(q,sinBR) {
    var 
elDIV document.createElement("DIV");
    if(
q==undefinedq="";
    if(!
sinBRq+="<br/>";
    
elDIV.innerHTML q;
    for(var 
a=0elDIV.childNodes.length>aa++) {
        
document.body.appendChildelDIV.childNodes[a].cloneNode(true) );
    }
}

// FUNCIONES PROTOTIPADAS NECESARIAS PARA PODER ESPERAR Y EJECUTAR DESPUÉS DE UNA FUNCIÓN OTRA
Function.prototype.setDespues = function(f) { this.despues f; }
Function.
prototype.declararFin = function() { this.fin true; }
Function.
prototype.reestablecerFin = function() { this.fin false; }
Function.
prototype.ejecutarDespuesAlFinalizar = function() {
    var 
oThis this;            // Para que funcione dentro del setInterval
    
this.comprobarFin setInterval( function() {
        var 
nombreFunc oThis.toString().substring"function ".lengthoThis.toString().indexOf("(") );
        
e("Comprobando: fin de "+nombreFunc+" es "+oThis.fin);
        if( 
oThis.fin == true ) {
            
oThis.reestablecerFin();
            
clearIntervaloThis.comprobarFin );
            
oThis.despues();
        }
    }, 
500);
}


function 
tardona() {
    
e("Entro en tardona");
    
// .... cosas que tardan
    // el setTimeout es sólo para simular que la ejecución de tardona() tarda 5 sgs
    
setTimeout( function() {
        
tardona.declararFin();
        
e("tardona.declararFin() ejecutado");
    } , 
5000);
}

function 
segundona() {
    
e("Entro en segundona!");
    
// .... cosas que tardan
    // el setTimeout es sólo para simular que la ejecución de segundona() tarda 5 sgs
    
setTimeout( function() {
        
segundona.declararFin();
        
e("segundona.declararFin() ejecutado");
    } , 
5000);
}

function 
tercerona() {
    
e("Entro en tercerona!");
}

function 
principal() {
    
// Primer bloque
    
tardona.setDespuessegundona );
    
tardona.ejecutarDespuesAlFinalizar();
    
tardona();
    
// Hilvanemos tercerona
    
segundona.setDespuestercerona );
    
segundona.ejecutarDespuesAlFinalizar();
}

window.onload principal
Como ves en principal(), primero le decimos que después de tardona() queremos ejecutar segundona(). Luego iniciamos la comprobación para ver si ha terminado tardona() para empezar su después (segundona()), y ya por fin arrancamos tardona().

Lo que ocurre es que se ejecuta tardona(), y cuando llega a su fin entonces cambia el estado de tardona.fin (pasando a ser true). Éste cambio es detectado por el setInterval comprobador dentro de tardona.ejecutarDespuesAlFinalizar(); entonces hace saltar tardona.despues que coincide con segundona().

A segundona le hemos dicho que le preceda tardona().


Y como ves todo funciona al parecer como debe.



Un saludo.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #5 (permalink)  
Antiguo 08/10/2007, 19:01
 
Fecha de Ingreso: septiembre-2005
Mensajes: 1.289
Antigüedad: 19 años, 2 meses
Puntos: 3
Re: como controlar la ejecucion...

wow, siempre al pi del cañon derkenuke, lo checare y vere que tal me resulta, perdon la demora por responder pero me he visto muy laboriado estos dias...
__________________
Wow! No se que decir...
  #6 (permalink)  
Antiguo 15/10/2007, 07:48
 
Fecha de Ingreso: septiembre-2005
Mensajes: 1.289
Antigüedad: 19 años, 2 meses
Puntos: 3
Re: como controlar la ejecucion...

Que tal, bueno, intento implementar el primer truco que me diste pero no me da, a lo mejor no estoy implementandolo correctamente.. lo utilizo en:

Código PHP:
function moveValList(listFromlistTo,origen){
     var 
len listTo.length;
     if (!
lenlen=0;
     for (var 
i=listFrom.length-1i>=0i--) {
          if (
listFrom.options[i].selected == true) {
              
s_frm listFrom.options[i].text;
              
s_val listFrom.options[i].value;
              if(
origen=='puesto'){
                  if(
listFrom.name=='save_puestos'){
                      
verificaRelacionFlujo(s_val);//esta es la funcion que se demora...
                      
                    
comprobador setInterval( function() {
                        if( 
finDeTardona == true ) {
                            
finDeTardona false;            // reestablecemos
                            
clearTimeoutcomprobador );    // paramos de comprobar
                            
listTo[len++] = new Option(s_frms_val);
                            
alert(i);
                            
listFrom.options[i] = null;//****
                        
}
                     }, 
500);
                     
                }else{
//Fin de IF save_puestos
                    
listTo[len++] = new Option(s_frms_val);
                    
listFrom.options[i] = null;
                }
              }else{  
                  
listTo[len++] = new Option(s_frms_val);
                  
listFrom.options[i] = null;
              }
              
alert('i = ' i);//----
            
}//fin del IF selected
        
}//Fin del FOR
   
}//fin de Funcion 
el problema esta en que al parecer el For sigue su camino y la variable de "i" me da -1 en la linea comentada con //**** , entonces al darme -1 me marca error en el objeto, menciono que el for continua por que tambien pongo un alert al final donde esta comentado con //---- y si me mustra ese alert antes que el del alert que esta antes de la linea que me genera el error, io crei que el for esperaria a que se cumpliera lo del comprovador, pero no lo hace, que hago mal?
__________________
Wow! No se que decir...
  #7 (permalink)  
Antiguo 15/10/2007, 10:34
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 1 mes
Puntos: 45
Re: como controlar la ejecucion...

Hola de nuevo zyon:

Veo que no has captado muy bien el concepto de mi código. Lo que tú esperas que haga es una especid de sleep() de php, o algo como espera aqui hasta que verificaRelacionFlujo(s_val) acabe.

Bueno, lo que pasa es que mi código es algo diferente. Mi código va por funciones. Es decir: Ejecuto funcion1, y cuando haya acabado ejecuto funcion2, y cuando ésta haya acabado ejecuto funcion3... es decir, en ningún momento paro la ejecución, sólo espero para llamar a la siguiente función.

En tu caso, no hay funciones separadas. Tú quieres que dentro de un for, se detenga la ejecución. Eso, de momento y en la versión 1.5 de javascript es imposible (aunque lo estoy investigando vivamente, tal vez veais un post mio próximamente. He visto que en 1.7 sí se puede hacer).

Te digo lo que yo haría en tu caso (como es lógico vas a necesitar más código). Una primera idea podría ser:
Código PHP:
function forConPausas() {
    for(var 
i=10i>=0i--) {
        
funcionQueTarda(i);
        
// esperamos a que acabe funcionQueTarda... para ejecutar la siguiente sentencia
        
procesarIteracion(i);
    }

Algo así. Pero vemos que, por la naturaleza del for, lo que haría es lanzar un funcionQueTarda(10), y después, terminaría la iteración, y sin esperar a nada, ejecutaría un funcionQueTarda(9). Ésto nos genera un problema, porque que yo sepa no hay manera de parar un for momentáneamente, de hacerle una pausa. Así que vamos a tener que utilizar otro sistema:
Código PHP:
function forConPausas() {
    
//for(var i=5; i>=0; i--) {
    
var i=5;        // Comenzamos el ciclo con la variable i con el valor inicial que tú quieras
    
e("Entro en la iteración de i: "+i+".");
    
funcionQueTarda(i);
    
procesarIteracion(i);
    
e("Fin de la iteración de i: "+i+".");
    
//}

Así puesto, no itera. Pero aquí procesarIteracion se encargaría de continuar el for (es decir, volver a llamar a funcionQueTarda(i-1)) en caso de que i>=0. Mejor ponemos que forConPausas() se dedique a hacer una iteración con el parámetro que le pasemos:
Código PHP:
function forConPausas(valorI) {
    
//for(var i=5; i>=0; i--) {
    
var i=valorI;        // Comenzamos el ciclo con la variable i con el valor inicial que tú quieras
    // ....
    // ....

Entonces, ¿cómo demoramos procesarIteracion(i) hasta que funcionQueTarda(i) acabe? Bueno, creo que tenemos que entender un par de conceptos. Ojo que viene parte complicada, y te digo por qué. Con mi código escribiríamos ésto así:
Código PHP:
function forConPausas(valorI) {
    
//for(var i=5; i>=0; i--) {
    
var i=valorI;        // Comenzamos el ciclo con la variable i con el valor inicial que tú quieras
    
e("Entro en la iteración de i: "+i+".");
    
funcionQueTarda.setDespuesprocesarIteracion );        // Después de funcionQueTarda quiero procesarIteracion
    
funcionQueTarda(i);            // Ejecución de la función en sí
    
funcionQueTarda.ejecutarDespuesAlFinalizar();        // Ésto sólo hace que ir comprobando para lanzar procesarIteracion después
    
e("Fin de la iteración de i: "+i+".");
    
//}

Pero algo falla. ¿Qué hay de los parámetros para procesarIteración? Los necesitamos, así que habrá que ponerlos. Voy a tener que darte una explicación rápida porque no sé si sabes ésto:

Hacer ésto es fácil:
Código PHP:
function alertar() {
    
alert("hola");
}
function 
ejecutador(funcion) {
    
funcion();
}
ejecutadoralertar ); 
ejecutador ejecuta la función que se le pase por parámetro. Muy bien si dicha función (alertar) no tiene parámetros ella. Pero si tiene parámetros no podemos hacer:
Código PHP:
function alertar(q) {
    
alert(q);
}
function 
ejecutador(funcion) {
    
funcion();
}
ejecutadoralertar("hola") ); 
Porque lo que estamos haciendo es primero ejecutar alertar("hola") y luego pasarle a ejecutador el resultado de esa sentencia anterior (undefined) así que falla. Lo que hay que hacer es un closure o almacenar los parámetros:
Código PHP:
function alertar(q) {
    
alert(q);
}
function 
ejecutador(funcion) {
    
funcion();
}

function 
alertarHola() {
    
alertar("hola");
}
ejecutadoralertarHola ); 
Vale, muy bien me dirás, pero no voy a almacenar los infinitos parámetros de esta forma tan poco automática. Se ha inventado un método para las funciones, un toClosure() que lo hace automáticamente:
Código PHP:
Function.prototype.toClosure = function() {
    var 
this;
    var 
arguments;
    return (function() {
        return 
f.apply(thisa);
    });
}
var 
alertarHola alertar.toClosure("hola"); 
Ahora la variable alertarHola contiene el mismo contenido que el anterior ejemplo. Pero es más cómodo:
Código PHP:
Function.prototype.toClosure = function() {
    var 
this;
    var 
arguments;
    return (function() {
        return 
f.apply(thisa);
    });
}

function 
alertar(q) { alert(q); }
function 
ejecutador(funcion) { funcion(); }

ejecutadoralertar.toClosure("hola") ); 
Bueno visto ésto de los closures o almacenamientos de los parámetros metámonos en harina. Hemos dicho que la primera ejecución es fácil. Se transcribiría en mi código así de limpio:
Código PHP:
function forConPausas(valorI) {
    
//for(var i=5; i>=0; i--) {
    
var i=valorI;        // Comenzamos el ciclo con la variable i con el valor inicial que tú quieras
    
e("Entro en la iteración de i: "+i+".");
    
funcionQueTarda.setDespuesprocesarIteracion.toClosure(i) );        // Después de funcionQueTarda quiero procesarIteracion
    
funcionQueTarda(i);            // Ejecución de la función en sí
    
funcionQueTarda.ejecutarDespuesAlFinalizar();        // Ésto sólo hace que ir comprobando para lanzar procesarIteracion después
    
e("Fin de la iteración de i: "+i+".");
    
//}

Y luego dentro de procesarIteracion veríamos si tenemos que seguir "iterando" o no. procesarIteracion podría ser algo así:
Código PHP:
function procesarIteracion(parametro) {
    
e("Entro en procesarIteracion con el parámetro: "+parametro+"."); 
    
// Aquí dentro va todo lo que debería hacer el for normalmente
    
e("Acabo de procesar "+parametro+".");
    
// ProcesarIteración también se encarga de continuar la iteración si todavía no hubiésemos llegado a donde queríamos llegar
    
if( --parametro >= ) {        // Continuamos con la iteración, con parametro-1
        
forConPausas(parametro);
    }



Te dejo un ejemplo completo que he comprobado que funciona. Tiene bastante contenido, pero como ya hemos visto el bloque que hace ejecutar una función después de otra, y el toClosure, y la función principal forConPausas y la iterativa procesarIteracion, creo que no te será duro entenderlo. Eso sí, leyendo poco a poco

EDIT: Me he pasado escribiendo: 10627 caracteres. Así que te posteo el código en el siguiente mensaje
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #8 (permalink)  
Antiguo 15/10/2007, 10:34
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 1 mes
Puntos: 45
Re: como controlar la ejecucion...

Código PHP:
<!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" xml:lang="es" lang="es">
<
head>
<
meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" />
<
meta name="Author" content="derkeNuke" />
<
title>P&#225;gina nueva</title>
<style type="text/css">

</
style>
</
head>

<
body>


<
script type="text/javascript">
<!--


// escribir en el documento una ristra (x)html fuera de tiempo de ejecución.
function e(q,sinBR) {
    var 
elDIV document.createElement("DIV");
    if(
q==undefinedq="";
    if(!
sinBRq+="<br/>";
    
elDIV.innerHTML q;
    for(var 
a=0elDIV.childNodes.length>aa++) {
        
document.body.appendChildelDIV.childNodes[a].cloneNode(true) );
    }
}


// FUNCIONES PROTOTIPADAS NECESARIAS PARA PODER ESPERAR Y EJECUTAR DESPUÉS DE UNA FUNCIÓN OTRA
Function.prototype.setDespues = function(f) { this.despues f; }
Function.
prototype.declararFin = function() { this.fin true; }
Function.
prototype.reestablecerFin = function() { this.fin false; }
Function.
prototype.ejecutarDespuesAlFinalizar = function() {
    var 
oThis this;            // Para que funcione dentro del setInterval
    
this.comprobarFin setInterval( function() {        // Cada 500ms comprobará si this ha terminado
        
var nombreFunc oThis.toString().substring"function ".lengthoThis.toString().indexOf("(") );
        
e("Comprobando: fin de "+nombreFunc+" es "+oThis.fin);
        if( 
oThis.fin == true ) {
            
oThis.reestablecerFin();                // Reestablecemos esta variable para el futuro
            
clearIntervaloThis.comprobarFin );    // Terminamos la comprobación redundante
            
oThis.despues();                        // Aquí es donde ejecutamos la función de despues
        
}
    }, 
500);
}
// GUARDAR LOS PARÁMETROS DE UNA FUNCIÓN PARA EJECUTARLA DESPUÉS
Function.prototype.toClosure = function() {
    var 
this;
    var 
arguments;
    return (function() {
        return 
f.apply(thisa);
    });
}


function 
funcionQueTarda(parametro) {
    
e("Entro en funcionQueTarda con el parámetro: "+parametro+".");
    
e("Tardaré en acabarme unos 5 segundos.");
    
// .... cosas que tardan
    // el setTimeout es sólo para simular que la ejecución de tardona() tarda 5 sgs. Tú en tu función sólo tendrías que poner:
    //  funcionQueTarda.declararFin();    al final de esta función
    
setTimeout( function() {
        
funcionQueTarda.declararFin();
        
e("Fin de funcionQueTarda -- funcionQueTarda.declararFin() ejecutado");
    } , 
5000);
    
e("funcionQueTarda está ejecutándose, y está tardando .... ");
}


function 
procesarIteracion(parametro) {
    
e("Entro en procesarIteracion con el parámetro: "+parametro+"."); 
    
// Aquí dentro va todo lo que debería hacer el for normalmente
    
e("Acabo de procesar "+parametro+".");
    
// ProcesarIteración también se encarga de continuar la iteración si todavía no hubiésemos llegado a donde queríamos llegar
    
if( --parametro >= ) {        // Continuamos con la iteración, con parametro-1
        
forConPausas(parametro);
    }
}

function 
forConPausas(valorI) {
    
//for(var i=5; i>=0; i--) {
    
var i=valorI;        // Comenzamos el ciclo con la variable i con el valor inicial que tú quieras
    
e("Entro en la iteración de i: "+i+".");
    
funcionQueTarda.setDespuesprocesarIteracion.toClosure(i) );        // Después de funcionQueTarda quiero procesarIteracion
    
funcionQueTarda(i);            // Ejecución de la función en sí
    
funcionQueTarda.ejecutarDespuesAlFinalizar();        // Ésto sólo hace que ir comprobando para lanzar procesarIteracion después
    
e("Fin de la iteración de i: "+i+".");
    
//}
}


window.onload forConPausas.toClosure(5);



// -->
</script>

</body>
</html> 
Te he puesto tambien en window.onload con un toClosure para que veas su utilidad y quizás comprendas mejor...





Bueno, lo siento por la graaaan chapa. Es que es un tema complicado que siempre me ha llamado la atención. Espero encontrar algún día una forma más fácil de hacer todo ésto.

Un saludo.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #9 (permalink)  
Antiguo 17/10/2007, 08:02
 
Fecha de Ingreso: septiembre-2005
Mensajes: 1.289
Antigüedad: 19 años, 2 meses
Puntos: 3
Re: como controlar la ejecucion...

ok, lo intentare, espero me resulte...
__________________
Wow! No se que decir...
  #10 (permalink)  
Antiguo 17/10/2007, 17:57
Avatar de MaBoRaK  
Fecha de Ingreso: abril-2003
Ubicación: La Paz - Bolivia
Mensajes: 2.003
Antigüedad: 21 años, 7 meses
Puntos: 35
Re: como controlar la ejecucion...

loading............


En teoría el interprete de javascript es BATCH o sea, que si dentro de un for tienes una función, dicha solo se continuará con el for cuando la función interna termine de interpretarse.

Asi que no se daría ningun caso en el que alguna función interna se ejecute ASINCRONAMENTE...............

Para mas detalles pueden depurar con Firebug, y verán como se interpreta javacript... entrando hasta lo mas profundo de las funciones... y una vez terminadas continuar con su proceso padre.

connection closed.
__________________

Maborak Technologies
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 (incluyéndote)




La zona horaria es GMT -6. Ahora son las 04:35.