Usando funções de callback em javascript para sucesso ou erro

Em mais um post sobre funções como parâmetro de outras funções no javascript, vou mostrar como fazer para passar uma série de funções para determinados fins – como em caso de sucesso, em caso de falha, etc…

Onde sempre vemos isso? Frameworks como jQuery e Prototype dão a opção de você escolher uma função de callback para sucesso de um evento, outra para falha, outra para quando se inicia o drag de um elemento na tela, e por aí vai. Isso é feito passando, ao invés de uma função, uma lista de funções. No caso, para poder dar nome a elas, usamos a estrutura de chave/valor (key/value).

O exemplo abaixo explica como a função wrapper() passa 2 parâmetros e duas funções de callback: uma para sucesso, outra para falha. Na primeira chamada, a função de callback chamada será a de sucesso, pois é possível efetuar a rotina. No outro caso, dará erro, então será usada a função de falha.

<!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>Untitled Document</title>
<script type="text/javascript">
function wrapper(par1, par2) {
    //verifica se o último parâmetro é uma função para chamá-la;
    //os demais parámetros são repassados para a função

    var lastArgument = arguments[arguments.length-1];
   
    try {
        //Classe Math possue o método max(), que retorna o maior valor entre dois parâmetros
        var sum = Math.max(par1, par2);
        //se não for erro, joga (throw) erro
        if(isNaN(sum))
            throw "not a valid result";
        //se chegar até aqui, é um resultado válido e chama função de sucesso
        lastArgument.onSuccess.call(this, sum);
    } catch(e) {
        //se não, chama a função de erro
        lastArgument.onFailure.call(this, e);
    }
       
   
}

function errorHandler(e) {
    alert("Error: " + e);
}

function myFunction(sum) {
    alert(sum);
}
wrapper(10, 2, {onSuccess: myFunction, onFailure:errorHandler}); //será chamado sucesso
wrapper(10, "a", {onSuccess: myFunction, onFailure:errorHandler}); //será chamado erro
</script>
</head>
<body>

</body>
</html>

 

Passando uma função e outros parâmetros para outra função em javascript

Seguindo o que comecei a explicar nesse post sobre como passar funções como parâmetro para outra no javascript, vou mostrar agora rapidamente como passar outros parâmetros – texto, string, o que você precisar.

Esse exemplo abaixo funciona para o caso de você saber exatamente quantos parâmetros serão passados para a função e quantos recebidos pela função de callback.

<!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>Untitled Document</title>
<script type="text/javascript">
function wrapper(par1, par2) {
    //verifica se o último parâmetro é uma função para chamá-la;
    //os demais parámetros são repassados para a função  
    if(arguments.length>0) {
        var lastArgument = arguments[arguments.length-1];
        if(typeof(lastArgument)=="function") {
            lastArgument.call(this, par1, par2);   
        }
    }
}
function myFunction(par1, par2) {
    alert(par1);
    alert(par2);
}
wrapper("a", "b", myFunction);
</script>
</head>
<body>
</body>
</html>

O exemplo funciona da seguinte forma: a função wrapper recebe duas strings e uma função. Nela, verifica-se se o último parâmetro é uma funcão e, se for, ela chama essa função passando essas duas strings como parâmetro.
Note que esse exemplo vale para a função sendo passada como último parâmetro. Ela pode ser passada em outra ordem, mas aí deve ser feita a devida checagem.

Nos próximos post, mostro como receber uma quantidade aleatória de parâmetros e tratar de repassá-los (usando JSON) e como definir funções de callback específicas dependendo de condições na wrapper.