Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

closure takeUntil

Oi, não entendi muito bem o porque na função takeUntil o times é "lembrado" e não reiniciado com o valor 3 toda vez que chamado.

//operator.js
export const takeUntil = (times ,fn) => 
  () => times-- > 0 && fn();

//app.js

const operation = takeUntil(3, () =>
  notasService
    .sumItems('2143')
    .then(console.log)
    .catch(console.log)
)
document
.querySelector("#myButton")
.onclick = operation
1 resposta
solução!

Oi Murillo!

Vou reescrever a função takeUntil para que ela fique um pouco mais legível:

const takeUntil = (times, fn) => {
    function segundaFn()  {
        return times-- > 0 && fn();
    }

    return segundaFn;
}

Podemos ver então que o return de takeUntil é a segundaFn. Como times e fn foram passados por parâmetro e portanto existem no escopo de takeUntil, a função segundaFn tem acesso a eles.

Vou adicionar uma variável a mais na função takeUntil para que a próxima explicação fique mais entendível:

const takeUntil = (times, fn) => {
    let currentCount = times;
    function segundaFn()  {
        return currentCount-- > 0 && fn();
    }

    return segundaFn;
}

A variável currentCount recebe o valor de times, e tem seu valor diminuido toda vez que segundaFn é executada.

Agora, vamos criar a variável operation que recebe como parâmetros 3 e () => console.log("oi") e chamá-la 4 vezes:

const operation = takeUntil(3, () => console.log("oi"));
operation();
operation();
operation();
operation();

Vamos analisar passo a passo o que acontece:

  1. takeUntil é chamada

  2. currentCount recebe o valor 3

  3. segundaFn é declarada

  4. segundaFn é retornada por takeUntil

  5. operation recebe segundaFn

  6. operation()

    • diminui o valor de currentCount (que vale 2 agora)
    • printa "oi"
  7. operation()

    • diminui o valor de currentCount (que vale 1 agora)
    • printa "oi"
  8. operation()

    • diminui o valor de currentCount (que vale 0 agora)
    • printa "oi"
  9. operation() não faz nada pois currentCount < 0

Observações super hiper importantes:

  • executar operation é a mesma coisa que executar segundaFn
  • currentCount recebe o valor 3 apenas uma vez na chamada de takeUntil. Ou seja, executar operation não atribui o valor de currentCount novamente.

Para confirmar que currentCount recebe o valor apenas uma vez, basta colocar modificar takeUntil para printar o valor inicial da variável

const takeUntil = (times, fn) => {
    let currentCount = times;
    console.log("valor inicial", currentCount);
    function segundaFn()  {
        return currentCount-- > 0 && fn();
    }

    return segundaFn;
}

Agora, a mesma sequência de comandos nos tratá o output:

valor inicial: 3
oi
oi
oi

Como esperado, apesar de operation ser chamada várias vezes, "valor inicial 3" foi impresso apenas uma vez.

Se ainda ficar com dúvidas, por favor comente aqui! Espero ter ajudado! :)