Pergunta

Fiz uma pergunta há algumas semanas sobre o uso do setTimeout para uma função fatorial, mas infelizmente foi com uma conta não registrada e nunca recebi uma resposta completa.

Minha questão principal é que eu gostaria de escrever uma função que calcule o fatorial de um número, mas usa os comandos SetTimeout ou SetInterval. O ímpeto por trás disso é redefinir um contador que o IE usa para evitar um aviso de script de longa duração. Atualmente, a função fatorial que tenho é:

function factorial(n) {
  return 0 === n || 1 === n ? 1 : n * factorial(n - 1)
}

No meu outro post, a JSumners teve a gentileza de me fornecer um código que tentou usar o setTimeout periodicamente ao calcular um fatorial:

function factorial(x) {
 executions++;
   if (x > 1) {
      if (executions % 20 === 0) {
          return (function() {
              var y = x;
              setTimeout(function(y) { return y*factorial(y-1); }, 1);
           });
      } else {
        return x*factorial(x-1);
      }
   } else {
  executions = 0;
      return 1;
   }
}

No código acima, ele deve teoricamente usar o comando setTimeout para executar a próxima multiplicação quando o número de execuções decorridas for um fator de 20 (mod 20). Infelizmente, o código não funciona e o que acontece é que, se tenta calcular o fatorial de um número maior que 20, o resultado é NAN. Se o número for menor que 20, a resposta estará correta.

Alguém conhece uma solução para esta ou outra maneira de calcular uma fatorial usando os comandos setTimeout ou setInterval?

Obrigado!

Foi útil?

Solução

É porque você está especificando y como um parâmetro que é undefined Quando executado porque não foi passado, você pode corrigi -lo, mudando isso:

setTimeout(function(y) { return y*factorial(y-1); }, 1);

Para isso:

setTimeout(function() { return y*factorial(y-1); }, 1);

No entanto, ainda será NaN Porque aqui:

      return (function() {
          var y = x;
          setTimeout(function() { return y*factorial(y-1); }, 1);
       });

Você ainda está devolvendo um função, não um número que pode ser multiplicado, para que você ainda não possa usar um setTimeout() dessa maneira. Você pode passar um retorno de chamada que é executado quando tudo estiver pronto, mas não pode recorrer e retornar a um chamador como este.

Outras dicas

O fator de estilo de retorno de chamada com cada etapa recorrente agendada com o setTimeout é:

// private helper function (recurrency with accumulation)
function _factorial(acc, n, callback){
  if(n==0){
    callback(acc);
  }else{
    var callback_wrapper = function(result){
       callback(result);
    };
    setTimeout(function(){_factorial(acc * n, n-1, callback_wrapper)}, 10);
  }
}

// public function
function factorial(n, callback){
  _factorial(1, n, callback);
}

// usage example
factorial(10, function(result){console.log(result)});

- Saúde, Lambder

http://lambder.com/

http://vanadiumjs.com/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top