04 agosto, 2008

Ejecución de una función en segmentos

En Dreaming in Javascript muestran una forma de tratar con las funciones Javascript cuya ejecución lleva más tiempo del previsto y aparece un mensaje indicando que el navegador no responde y si se quiere detener el programa. La idea es detectar si el proceso está llevando más tiempo del previsto y usar la función setTimeout(nombreFuncion,0) para rellamar a la función y que continúe el trabajo pero empezando de nuevo la cuenta atrás para que aparezca el aviso. Una forma de detectar si el tiempo es excesivo sería comprobando el tiempo transcurrido a cada iteración del bucle. Para poder continuar con la ejecución de la función después del setTimeout, es necesario guardar los datos con los que se esté trabajando. Un buen lugar para hacerlo es la misma función. Para ello, se puede usar la sintaxis nombreFuncion.variable=valor que permite crear una variable persistente entre llamadas. Como ejemplo, en el blog proponen una función que calcula los factores primos de un número especificado y se prueba a llamar a la función con el número 100 000:

function findPrimes2(topCandidate) {
       var persist=arguments.callee;
       var tries=0;
       if (persist.candidate===undefined) {
           persist.candidate=2;
           persist.primes=[];
           persist.topCandidate=topCandidate;
       }
       keepTrying = true;
       while (persist.candidate <= persist.topCandidate && keepTrying) {
           trialDivisor = 2;
           prime = true;
           while (trialDivisor * trialDivisor <= persist.candidate) {
               if (persist.candidate % trialDivisor === 0) {
                   prime = false;
                   break;
               }
               trialDivisor++;
           }
           if (prime) {
               persist.primes.push(persist.candidate);
           }
           persist.candidate++;
           tries++;
           if (tries>1000) {
               keepTrying=false;
           }
       }
       if (keepTrying) {
           persist.candidate=undefined;
           alert(persist.primes.length);
       } else {
           setTimeout(persist,0);
       }
   }

findPrimes2(100000);

Publicar un comentario en la entrada

Últimos links en indiza.com