Front End

13 dez, 2018

Limitando execução de função com takeUntil

100 visualizações
Publicidade

Geralmente, durante o uso de softwares, muitas funções devem ser/são executadas. Indo um pouco mais além, dificilmente você verá um sistema (seja web ou desktop) que não possua pelo menos uma função.

Imagine que estamos trabalhando em um sistema na web (webapp), nosso sistema é para cadastro de pacientes e uma das nossas funcionalidades é realizar a importação de dados de uma fonte externa (outro sistema), e sabendo disso, nosso cliente pediu que a função de exportação só pudesse ser executada uma vez.

Caso a mesma tenha sido executada, ela não pode mais ser disparada. Como podemos criar essa nova funcionalidade e resolver o problema do nosso cliente?

Conhecendo a takeUntil

Para esse problema podemos implementar nossa própria takeUntil. Ela será uma função responsável por executar determinada função até uma certa quantidade de vezes (definida via parâmetro). Podemos começar criando nossa takeUntil:

const takeUntil = (times, fn) => {
    // implementação...
}

Nossa função recebe dois parâmetros (até o momento para nossa necessidade), sendo eles:

  • times: quantidade de vezes que uma determinada função poderá ser executada
  • fn: função que será executada até uma determinada quantidade de vezes

Repare que um parâmetro depende do outro.

Agora, como podemos implementar o corpo de nossa função?

Implementando a takeUntil

O primeiro passo será retornar uma nova função (com sua execução limitada):

const takeUntil = (times, fn) => {
    return () => {}
}

Agora já podemos criar nossa função de forma limitada:

const importarDados = () => console.log('Importando os dados...')

const fn = takeUntil(1, importarDados)

Repare que criamos uma função chamada importarDados, que apenas irá logar uma mensagem simulando a importação de dados. Depois, fizemos o uso da nossa função takeUntil para criarmos uma nova função – agora com sua execução limitada em apenas uma única vez (pois passamos o primeiro parâmetro como 1).

Porém, se tentarmos executar nossa nova função:

fn()

Nada irá acontecer. Por que? Isso acontece porque nossa função takeUntil ainda não foi implementada e está apenas retornando uma função que nada faz.

Chega de mais delongas e vamos ao que interessa: implementar a função takeUntil. Ela deverá funcionar da seguinte maneira:

  • Verificar se a quantidade de execução não foi atingida
  • Caso ainda não foi atingida, execute ela
  • E por último, diminua o número de vezes que ainda podemos executá-la

Agora que já sabemos como ela irá funcionar, podemos começar sua implementação.

Verificar se a quantidade de execução não foi atingida

Para realizar a verificação se ainda podemos ou não executar a função, podemos simplesmente verificar se nosso parâmetro times ainda é maior do que zero:

const takeUntil = (times, fn) => {
    return () => {
        if (times > 0) {
            // pode executar...
        }
    }
}

Legal, a verificação foi feita de forma simplista através de um simples if.

Caso ainda não tenha sido atingida, execute-a

Com o passo anterior feito, garantimos que nossa função executará apenas quando ainda puder – apenas trocamos o comentário anterior pela chamada da função:

const takeUntil = (times, fn) => {
    return () => {
        if (times > 0) {
            fn()
        }
    }
}

Pronto, nossa função será executada somente onde nossa condição é verdadeira. Ou seja, a quantidade (times) de vezes ainda é maior do que zero.

E por último, diminua o número de vezes que ainda podemos executá-la

Por fim, com tudo pronto, precisamos apenas diminuir a quantidade de vezes que ainda podemos executar nossa função:

const takeUntil = (times, fn) => {
    return () => {
        if (times > 0) {
            fn()
        }
        times--
    }
}

Maravilha! Tudo deve estar funcionando. Vamos testar?

fn()
fn()
fn()
fn()
fn()

Aqui pedimos para nossa função ser executada cinco vezes, mas, só veremos a mensagem no console uma única vez.

No entanto, ainda não podemos comemorar. Daremos uma olhada no código final (até então) da função takeUntil.

const takeUntil = (times, fn) => {
    return () => {
        if (times > 0) {
            fn()
        }
        times--
    }
}

Está muito verboso. Será que não podemos melhorá-lo? Sim, podemos deixá-lo bem menor e mais simples:

const takeUntil = (times, fn) => () => times-- > 0 && fn()

Feito. Em apenas uma linha realizamos todos os passos anteriormente destacados.

Caso queira ver o código em funcionamento:

Conclusão

Realizamos a criação/implementação da função takeUntil. Com ela, conseguimos limitar a execução de uma determinada função até uma certa quantidade de vezes.

Uma biblioteca muito famosa que faz uso dessa função é a RxJS (claro que com uma implementação diferente).

E aí? Você já conhecia a função takeUntil? Não deixe de comentar!

Até a próxima!