<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Lukita Moreno</title>
    <description>The latest articles on Forem by Lukita Moreno (@devlmoreno).</description>
    <link>https://forem.com/devlmoreno</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F687683%2F59d17463-5173-42e6-84be-0afe0189463d.jpg</url>
      <title>Forem: Lukita Moreno</title>
      <link>https://forem.com/devlmoreno</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/devlmoreno"/>
    <language>en</language>
    <item>
      <title>[PHP] Verificar se o CPF é numericamente válido</title>
      <dc:creator>Lukita Moreno</dc:creator>
      <pubDate>Fri, 27 Jan 2023 16:18:49 +0000</pubDate>
      <link>https://forem.com/devlmoreno/php-verificar-se-o-cpf-e-valido-2hd8</link>
      <guid>https://forem.com/devlmoreno/php-verificar-se-o-cpf-e-valido-2hd8</guid>
      <description>&lt;p&gt;Opaaa, tudo certo ? como vocês estão ?&lt;br&gt;&lt;br&gt;
Bom ... algumas pessoas podem ter a mesma dúvida que eu tive a um tempo atrás relacionada a como o cálculo para verificar se o CPF é válido é feito.&lt;br&gt;
Eis que encontro um blog onde é explicado passo a passo de como é feita essa validação -&amp;gt; &lt;a href="https://www.macoratti.net/alg_cpf.htm"&gt;Algoritmo CPF válido&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Com a regra de negócio em mãos resolvi transformar a lógica em código.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

$cpf = (string) 74305429055;
$firstVerifiedDigit = $secondVerifiedDigit = 0;

// ## Início cálculo primeiro digito
// pegar os 9 primeiros digitos
$firstNineDigits = substr($cpf, 0, 9);

$countFirst = 0;
$multiplierFirst = 10;
for ($i = 0; $i &amp;lt; 9; $i++) {
    $countFirst += $firstNineDigits[$i] * $multiplierFirst--;
}
echo "\nsoma dos digitos múltiplicados da esquerda para direita com um valor decremental começando por 10: $countFirst\n";

// dividindo a soma (count)  por 11 para obter o resto
$remainder = $countFirst % 11;
echo "\nResto da divisão: $remainder\n";

// Se o resto da divisão for menor que 2, então o dígito é igual a 0 (Zero). -&amp;gt; Como iniciamos o $firstVerifiedDigit com 0 não precisamos da validação
// Se o resto da divisão for maior ou igual a 2, então o dígito verificador é igual a 11 menos o resto da divisão (11 - resto)
if ($remainder &amp;gt;= 2) {
    $firstVerifiedDigit = 11 - $remainder;
}
echo "\nValor do primeiro dígito verificador: $firstVerifiedDigit\n";
// ## Fim cálculo primeiro digito

// ## Início cálculo segundo digito
// adicionando o primeiro digito verificador ao final do cpf
$cpfWithFirstDigit = $firstNineDigits . $firstVerifiedDigit;
echo "\nCPF com o primeiro dígito verificado ao final: $cpfWithFirstDigit\n";

$countSecond = 0;
$multiplierSecond = 11;
for ($i = 0; $i &amp;lt; 10; $i++) {
    $countSecond += $cpfWithFirstDigit[$i] * $multiplierSecond--;
}
echo "\nsoma dos digitos múltiplicados da esquerda para direita com um valor decremental começando por 11: $countSecond\n";

// dividindo a soma (count)  por 11 para obter o resto
$remainder = $countSecond % 11;
echo "\nResto da divisão: $remainder\n";

// Se o resto da divisão for menor que 2, então o dígito é igual a 0 (Zero). -&amp;gt; Como iniciamos o $secondVerifiedDigit com 0 não precisamos da validação
// Se o resto da divisão for maior ou igual a 2, então o dígito verificador é igual a 11 menos o resto da divisão (11 - resto)
if ($remainder &amp;gt;= 2) {
    $secondVerifiedDigit = 11 - $remainder;
}
echo "\nValor do segundo dígito verificador: $secondVerifiedDigit\n";
// ## Fim cálculo segundo digito

// adicionando o segundo digito verificador ao final do cpf
$cpfValid = $cpfWithFirstDigit . $secondVerifiedDigit;
echo "\nCPF: $cpfValid\n";

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tentei deixar bem explicado cada etapa da validação.&lt;br&gt;
Repo: &lt;a href="https://github.com/dev-lmoreno/validateCpf"&gt;https://github.com/dev-lmoreno/validateCpf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;vlwww flwww&lt;/p&gt;

&lt;p&gt;referência: &lt;a href="https://www.macoratti.net/alg_cpf.htm"&gt;https://www.macoratti.net/alg_cpf.htm&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>JavaScript Síncrono e Assíncrono</title>
      <dc:creator>Lukita Moreno</dc:creator>
      <pubDate>Wed, 14 Sep 2022 01:35:37 +0000</pubDate>
      <link>https://forem.com/devlmoreno/javascript-sincrono-e-assincrono-1leb</link>
      <guid>https://forem.com/devlmoreno/javascript-sincrono-e-assincrono-1leb</guid>
      <description>&lt;p&gt;Ooopa, bom dia, boa tarde e boa noite pessoal, como vcs estão ??? Espero que bem o/&lt;/p&gt;

&lt;p&gt;Nesse artigo abordaremos sobre alguns tópicos relacionados a JavaScript Assíncrono. Entre eles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Callbacks&lt;/li&gt;
&lt;li&gt;Promises&lt;/li&gt;
&lt;li&gt;Async/Await&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para iniciarmos o entendimento, precisamos saber que nosso código JavaScript é executado&lt;br&gt;
em uma única thread, ou seja, ao ser executado só pode fazer uma ação por vez.&lt;br&gt;
O código é executado da primeira linha a última em ordem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const firstFunction = () =&amp;gt; {
    console.log('First Function called!');
}

const secondFunction = () =&amp;gt; {
    console.log('Second Function called!!');
}

console.log('Calling firstFunction');
firstFunction(); // Resultado: First Function called!

console.log('Calling secondFunction');
secondFunction(); // Resultado: Second Function called!!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima pode-se observar que criamos as funções firstFunction e secondFunction, logo em seguida nós chamamos a firstFunction para ser executada e depois a secondFunction. Repare que nesse trecho existe uma ordem a ser seguida para execução, primeiro a firstFunction e depois a secondFunction. Esse é um exemplo do funcionamento do Js síncrono.&lt;/p&gt;




&lt;p&gt;Agora, sabendo como é o funcionamento síncrono, o que vc pensa quando falamos sobre Js assíncrono ?&lt;/p&gt;

&lt;p&gt;Para um melhor entendimento é bom sabermos que no código assíncrono ele pode iniciar seu processo nesse exato momento e pode ser finalizado daqui algum tempo, ou seja, o código leva um tempo para ser executado e também pode ser sucedido ou não.&lt;/p&gt;

&lt;p&gt;Um simples exemplo de funcionamento do Js assíncrono é a função setTimeout(). Onde a mesma será&lt;br&gt;
executada após X segundos no qual nós definimos em sua chamada. No exemplo abaixo o console.log dentro da função setTimeout só será exibido após 3 segundos, os demais logs serão exibidos sequencialmente, isso porque quando utilizamos a função setTimeout passamos a utilizar para esse caso o Js de forma assíncrona e os demais logs são executados de forma síncrona.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log('Início do exemplo');

setTimeout(() =&amp;gt; {
    console.log('Esse log irá aparecer depois de 3 segundos');
}, 3000);

console.log('Esse log e o log abaixo irão aparecer antes do log dentro do setTimeOut');
console.log('Fim do exemplo');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alguns exemplos mais reais de utilização são as requesições que fazemos as API's e interações com o banco de dados (inserções, consultas, etc). Quando fazemos a request podemos aguardar cerca de alguns segundos para receber uma resposta da API. Veremos um exemplo mais prático sobre realizar uma requisição no decorrer do artigo.&lt;/p&gt;

&lt;p&gt;Lembram que foi comentado um pouco acima sobre o Js ser executado em uma única thread ? Pois então, as requisições são entregues para ser executadas em uma thread separada da atual. Por conta disso mesmo fazendo uma requisição em nosso código ele segue o jogo, fazendo o que precisa. No momento que a requisição é feita uma nova thread para ela é criada, enquanto isso o código que nós escrevemos vai sendo executado em sua "main thread".&lt;/p&gt;

&lt;p&gt;Para tratar esse códigos assíncronos nós temos algumas maneiras, entre elas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Callbacks&lt;/li&gt;
&lt;li&gt;Promises&lt;/li&gt;
&lt;li&gt;Promises com Async/Await&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Durante os exemplos e explições sobre esses tópicos vamos utilizar como base a ideia de consumir uma API de pokemóns :D&lt;br&gt;
Algo semelhante ao funcionamento dessa aplicação &lt;a href="https://codeboost.com.br/projetos/pokeapi/"&gt;https://codeboost.com.br/projetos/pokeapi/&lt;/a&gt;, onde podemos filtrar no lado esquerdo o tipo e como resposta temos os pokemons de tal tipo.&lt;br&gt;
Vamos simular uma aplicação onde primeiro precisamos fazer uma requisição para a API de pokemon que nos retornará uma lista de pokemon por tipos, ou seja, vamos procurar por um tipo de pokemon e será nos retornado uma lista com tais pokemons. Em seguida, com o nome dos pokemons em mãos nós iremos fazer uma segunda requisição para ver detalhes sobre um único pokemon.&lt;br&gt;
Nossa premissa nesse fluxo é que só podemos fazer a segunda request com o nome dos pokemons em mãos e para conseguir o nome é apenas fazendo a primeira requisição.&lt;/p&gt;

&lt;p&gt;Nesse exemplo sobre Callbacks nós estamos simulando a requisição para a API.&lt;br&gt;
Reparem que no resultado dos logs o valor do nosso retorno da API no nosso logs fica como 'undefined'. Isso acontece por conta do síncronismo do Js, no momento que fazemos o log das informações nós ainda não temos o retorno da API. Notem também que o log informando que estamos aguardando o retorno da API aparece por último, pois ele se encontra dentro do setTimeout e por consequencia será exibido após os 2 segundos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getPokemonByType = (type) =&amp;gt; {
    console.log('Inicio da função getPokemonByType');

    setTimeout(() =&amp;gt; {
        // Simulando o tempo de resposta da API
        console.log('Aguardando retorno da API - 2 segundos');

        // Simulando o retorno da API
        return [
            'Squirtle', 'Wartortle', 'Blastoise'
        ];
    }, 2000);
};

// Simulando requisição para API
const pokemonsByType = getPokemonByType('water');

console.log('Retorno da API: ', { pokemonsByType });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Resultado dos logs  

Inicio da função getPokemonByType
Retorno da API:  undefined
Aguardando retorno da API - 2 segundos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse fluxo nos temos um problema. Estamos tentando exibir a lista de pokemons do tipo água porém no momento que estamos fazendo o log disso nós não possuímos o retorno da API.&lt;br&gt;
Como podemos solucionar esse problema ?&lt;br&gt;
Isso mesmo, através de Callbacks :D&lt;/p&gt;

&lt;p&gt;Para podemos iniciar a solução vamos para uma breve e simples explicação do que são Callbacks.&lt;br&gt;
Callbacks são nada mais e nada menos que funções que são passadas por argumento/parâmetro para outras outras funções, permitindo que uma função chame outra. Lembrando que para os casos de callback uma função que está sendo passada por parâmetro só será executada após a finalização da função que está recebendo como parâmetro.&lt;/p&gt;

&lt;p&gt;Nesse exemplo nós chamamos a função firstFunction passando como parâmetro a função secondFunction, ou seja, recebemos como callback a função secondFunction na função&lt;br&gt;
firstFunction. Lembrando que a secondFunction só será executa aqui após a finalização da firstFunction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const firstFunction = (callback) =&amp;gt; {
    console.log('First Function called!');
    callback();
}

const secondFunction = () =&amp;gt; {
    console.log('Second Function called!!');
}

console.log('Calling firstFunction');
firstFunction(secondFunction); 
/* Resultado
Calling firstFunction
First Function called!
Second Function called!!
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com esse entendimento em mãos, podemos aplicar essa solução para o nosso caso de uso da API de pokemons, certo ? vamos nessa ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getPokemonByType = (type, callback) =&amp;gt; {
    console.log('Inicio da função getPokemonByType');

    setTimeout(() =&amp;gt; {
        // Simulando o tempo de resposta da API
        console.log('Aguardando retorno da API - 2 segundos');

        // Simulando o retorno da API
        // Nesse caso com callback só será retornado após a finalização da função setTimeout
        callback(['Squirtle', 'Wartortle', 'Blastoise']);
    }, 2000);
};

// Simulando requisição para API
// Aqui temos um callback sendo passado para a função getPokemonByType onde logamos o retorno da API
const pokemonsByType = getPokemonByType('water', (pokemonsByType) =&amp;gt; {
    console.log('Retorno da API: ', { pokemonsByType });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Resultado dos logs
Inicio da função getPokemonByType
Aguardando retorno da API - 2 segundos
Retorno da API:  { pokemonsByType: [ 'Squirtle', 'Wartortle', 'Blastoise' ] }
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Surgiu um cenário agora em que precisamos pegar os detalhes de algum pokemon da lista.&lt;br&gt;
Para isso, vamos implementar uma função getPokemonDetail onde vamos receber por parâmetro um indice do array que é o nome de um pokemon e trazer os detalhes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getPokemonByType = (type, callback) =&amp;gt; {
    console.log('Inicio da função getPokemonByType');

    setTimeout(() =&amp;gt; {
        // Simulando o tempo de resposta da API
        console.log('Aguardando retorno da API - 2 segundos');

        // Simulando o retorno da API
        // Nesse caso com callback só será retornado após a finalização da função setTimeout
        callback(['Squirtle', 'Wartortle', 'Blastoise']);
    }, 2000);
};

// Função que recebe o nome de um pokemon e um callback
// Após 2 segundos e meio chamamos a função de callback definida na linha 28, onde exibimobos apenas alguns logs
const getPokemonDetail = ((pokemon, callback) =&amp;gt; {
    setTimeout(() =&amp;gt; {
        callback(`O pokemon ${pokemon} é da primeira geração`);
    }, 2500);
});

// Simulando requisição para API
// Aqui temos um callback sendo passado para a função getPokemonByType onde logamos o retorno da API
const pokemonsByType = getPokemonByType('water', (pokemonsByType) =&amp;gt; {
    console.log('Retorno da API: ', pokemonsByType);
    console.log('Chamando a API de detalhes passando o pokemon Squirtle');

    // Chamada da função getPokemonDetail passando o primeiro valor do array retornado e um callback que recebe o retorno da execução da função.
    getPokemonDetail(pokemonsByType[0], (detail) =&amp;gt; {
        console.log('Nessa função de callback recebemos o retorno com os detalhes do pokemon');
        console.log('Detalhes (retorno da execução da função getPokemonDetail): ', detail);
    });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inicio da função getPokemonByType
Aguardando retorno da API - 2 segundos
Retorno da API:  [ 'Squirtle', 'Wartortle', 'Blastoise' ]
Chamando a API de detalhes passando o pokemon Squirtle
Nessa função de callback recebemos o retorno com os detalhes do pokemon
Detalhes (retorno da execução da função getPokemonDetail):  O pokemon Squirtle é da primeira geração
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caso surgi-se um novo cenário onde precisássemos fazer uma outra requisição após receber o retorno da função getPokemonDetail nós passaríamos a ter um "problema" ... Qual ?&lt;br&gt;
Então, reparem que nesse código de exemplo que temos até o momento estamos chamando a função getPokemonByType e passando um callback, em seguida chamando a função getPokemonDetail e passando um outro callback e se tivesse que implementar esse novo cenário nós chamariamos essa nova função e passariamos um outro callback.&lt;br&gt;
Com isso entramos no chamado "callback hell", onde passamos a ter uma série de callbacks aninhados, dificultando a visualização do código e até mesmo deixando seu entendimento muito confuso.&lt;/p&gt;

&lt;p&gt;Para sanar esse problema foram criadas as Promises. Bora lá dar inicio nesse segundo método.&lt;br&gt;
As promises são a evolução do callback, em uma definição mais conceitual promise é um objeto em Js que permite a execução de processamentos de forma assíncrona. Nela vamos ter o valor da exução salvo, sendo erro ou sucesso.&lt;/p&gt;

&lt;p&gt;Bom ... vamos para a prática que deve ficar mais simples o entendimento.&lt;br&gt;
Como primeiro passo vamos converter o início do nosso código onde utilizavamos callbacks para que passemos a utilizar promises.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getPokemonByTypePromise = (type) =&amp;gt; {
    // iniciando a promise
    // resolve - retorno success
    // reject - error
    return new Promise((resolve, reject) =&amp;gt; {
        const error = false; // alterar para true para cair no reject

        if (error) {
            reject(new Error(`Ocorreu um erro ao listar os pokemons do tipo ${type}`));
        }

        console.log('Retorno da API caso sucesso');
        resolve(['Squirtle', 'Wartortle', 'Blastoise']);
    })
}

getPokemonByTypePromise('water')
    // chamamos o then caso o fluxo caia no resolve
    // aqui recebemos o retorno do resolve, no caso o array dos pokemons do tipo water
    .then((pokemonsByType) =&amp;gt; {
        console.log(`Lista dos pokemons do tipo water: `, pokemonsByType);
    })
    // aqui caso o error seja true recebemos o retorno reject, nesse caso a mensagem de erro
    .catch((error) =&amp;gt; {
        console.log(error);
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Resultado dos logs
Retorno da API caso sucesso
Lista dos pokemons do tipo water:  [ 'Squirtle', 'Wartortle', 'Blastoise' ]
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora como segundo momento, vamos refatorar o restante do código para deixar utilizar callbacks e começar a utilizar promises.&lt;br&gt;
O funcionamento de nosso código é o mesmo porém agora com Promise.&lt;br&gt;
Reparem que agora o código ficou menor e mais legível, mais fácil de ler e entender. Com isso o problema do "callback hell" foi resolvido.&lt;br&gt;
Algumas observações sobre as promises:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Temos 2 maneiras de iniciar uma promise
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Maneira 1
const firstFunction = new Promise((resolve, reject) =&amp;gt; {
    const error = false;

    if (error) {
        reject('error');
    }

    resolve('success');
});

// Maneira 2
const secondFunction = () =&amp;gt; {
    return new Promise((resolve, reject) =&amp;gt; {
        const error = false;

        if (error) {
            reject('error');
        }

        resolve('success');
    })
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Caso uma promise execute outra, a promise anterior tem acesso ao retorno da primeira promise.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vamos ver como ficou o código com promises:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getPokemonByTypePromise = (type) =&amp;gt; {
    // iniciando a Promise
    // resolve - retorno success
    // reject - error
    return new Promise((resolve, reject) =&amp;gt; {
        const error = false; // alterar para true para cair no reject

        if (error) {
            reject(new Error(`Ocorreu um erro ao listar os pokemons do tipo ${type}`));
        }

        console.log('Retorno da API caso sucesso');
        resolve(['Squirtle', 'Wartortle', 'Blastoise']);
    })
}

const getPokemonDetailPromise = (pokemon) =&amp;gt; {
        return new Promise((resolve, reject) =&amp;gt; {
            const error = false; // alterar para true para cair no reject

            if (error) {
                reject(new Error(`Ocorre um erro ao gerar os detalhes do pokemon ${pokemon}`));
            }

            console.log('Retorno da API caso sucesso');
            resolve(`O pokemon ${pokemon} é da primeira geração`);
        });
};

getPokemonByTypePromise('water')
    // chamamos o then caso o fluxo caia no resolve
    // aqui recebemos o retorno do resolve, no caso o array dos pokemons do tipo water
    .then((pokemonsByType) =&amp;gt; {
        console.log(`Lista dos pokemons do tipo water: `, pokemonsByType);
        // aqui vamos retornar o resultado da função getPokemonDetailPromise
        return getPokemonDetailPromise(pokemonsByType[0]);
    }).then((detail) =&amp;gt; { // nesse then nós temos acesso ao resolve da Promise da função getPokemonDetailPromise
        console.log('Detalhes (retorno da execução da função getPokemonDetailPromise): ', detail);
    })
    // aqui caso o error seja true recebemos o retorno reject, nesse caso a mensagem de erro
    .catch((error) =&amp;gt; {
        console.log(error);
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Resultado dos logs
Retorno da API caso sucesso
Lista dos pokemons do tipo water:  [ 'Squirtle', 'Wartortle', 'Blastoise' ]
Retorno da API caso sucesso
Detalhes (retorno da execução da função getPokemonDetailPromise):  O pokemon Squirtle é da primeira geração
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um plus sobre promises é que é possível executar todas promises de uma vez utilizando o &lt;code&gt;Promise.all()&lt;/code&gt;.&lt;br&gt;
Segue exemplo onde temos 2 promises, a primeira é executada em 2 segundos e a segunda em 5 segundos, só teremos o resultado após a finalizar a execução da segunda promise que leva mais tempo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const firstPromise = new Promise((resolve, reject) =&amp;gt; {
    setTimeout(() =&amp;gt; {
        const error = false;

        if (error) {
            reject('error');
        }

        resolve('success-1');
    }, 2000);
});

const secondPromise = new Promise((resolve, reject) =&amp;gt; {
    setTimeout(() =&amp;gt; {
        const error = false;

        if (error) {
            reject('error');
        }

        resolve('success-2');
    }, 5000);
});

Promise.all([firstPromise, secondPromise]).then(result =&amp;gt; {
    console.log(result);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Resultado dos logs
[ 'success-1', 'success-2' ]
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos para o Async/Await que é uma forma para consumirmos as Promises.&lt;br&gt;
Para utilizar o Async/Await precisamos que a função seja assíncrona como no exemplo abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const showFirstEvolution = async() =&amp;gt; {

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utilizando Async/Await o código abaixo de onde estiver sendo utilizado só vai ser executado após as promises serem resolvidas.&lt;br&gt;
Para que possamos capturar as rejects bastas utilizarmos Try/Catch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getPokemonByTypePromise = (type) =&amp;gt; {
    // iniciando a Promise
    // resolve - retorno success
    // reject - error
    return new Promise((resolve, reject) =&amp;gt; {
        const error = false; // alterar para true para cair no reject

        if (error) {
            reject(new Error(`Ocorreu um erro ao listar os pokemons do tipo ${type}`));
        }

        console.log('Retorno da API caso sucesso');
        resolve(['Squirtle', 'Wartortle', 'Blastoise']);
    })
}

const getPokemonDetailPromise = (pokemon) =&amp;gt; {
        return new Promise((resolve, reject) =&amp;gt; {
            const error = false; // alterar para true para cair no reject

            if (error) {
                reject(new Error(`Ocorre um erro ao gerar os detalhes do pokemon ${pokemon}`));
            }

            console.log('Retorno da API caso sucesso');
            resolve(`O pokemon ${pokemon} é da primeira geração`);
        });
};

const showFirstEvolution = async() =&amp;gt; {
    try {
        // Nossa função getPokemonByTypePromise retornara o resolve e esse resolve ficará salvo na variável pokemonsByType
        const pokemonsByType = await getPokemonByTypePromise('water');
        console.log('Executou a função getPokemonByTypePromise e foi resolvida');

        const pokemonDetail = await getPokemonDetailPromise(pokemonsByType);
        console.log('Executou a função getPokemonDetailPromise e foi resolvida');

        console.log('Esse log só irá aparecer depois da execução das 2 funções');
        console.log('pokemonsByType: ', pokemonsByType);
        console.log('pokemonDetail: ', pokemonDetail);
        // Notem que esse log só aparece depois dos códigos acima serem executados.
        // Isso acontece por conta do Async/Await, com o await nós esperamos a promise ser resolvida ou rejeitada para assim dar seguimento no fluxo do código.
        console.log('Fim da execução');
    } catch (error) {
        // Para captturar o reject das promises basta utilizarmos try/catch
        console.log('Um erro ocorreu.', error);
    }
}

showFirstEvolution();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Retorno da API caso sucesso
Executou a função getPokemonByTypePromise e foi resolvida
Retorno da API caso sucesso
Executou a função getPokemonDetailPromise e foi resolvida
Esse log só irá aparecer depois da execução das 2 funções
pokemonsByType:  [ 'Squirtle', 'Wartortle', 'Blastoise' ]
pokemonDetail:  O pokemon Squirtle,Wartortle,Blastoise é da primeira geração
Fim da execução
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Temos aqui também um exemplo real de uma API sendo consumida onde utilizamos promises e Async/Await.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const axios = require('axios');

// Exemplo real consumindo uma promise
axios.get("https://pokeapi.co/api/v2/pokemon/squirtle").then((response) =&amp;gt; {
    console.log(response.data);
}).catch((error) =&amp;gt; {
    console.log(error);
});

// Exemplo real utilizando asyn/await
const getSquirtle = async() =&amp;gt; {
    try {
        const {data} = await axios.get("https://pokeapi.co/api/v2/pokemon/squirtle");
        console.log(data);
    } catch (error) {
        console.log(error);
    }
}

getSquirtle();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Tipos de Volumes no Docker</title>
      <dc:creator>Lukita Moreno</dc:creator>
      <pubDate>Sat, 04 Sep 2021 15:49:00 +0000</pubDate>
      <link>https://forem.com/devlmoreno/tipos-de-volumes-no-docker-370b</link>
      <guid>https://forem.com/devlmoreno/tipos-de-volumes-no-docker-370b</guid>
      <description>&lt;h2&gt;
  
  
  1. Para que serve o volume no Docker ?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tknbdi0780vjbch9o0a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tknbdi0780vjbch9o0a.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Basicamente utilizamos o volume para fazer a persistência de dados entre nossa máquina e o container.  &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Tipos de Volume
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Bind-mount&lt;/li&gt;
&lt;li&gt;Volume / Volume Nomeado&lt;/li&gt;
&lt;li&gt;Volume Temporário
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Bind-mount
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Exemplo de uso
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;docker run -it \&lt;br&gt;
-v /home/devlmoreno/docker-volumes/my-folder-bind:/my-app-docker \&lt;br&gt;
ubuntu:20.04  &lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* Para exemplificar o uso, começamos criando um diretório em nosso sistema com o nome *'my-folder-bind'*, logo em seguida criamos o container.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gmjc9k1aueduj1qriya0.png)  
* Por fim criamos um arquivo (*bind-mount.txt*) em nosso sistema (podendo ser a criação do arquivo dentro do container também). Pode-se observar que o arquivo é exibido normalmente tanto dentro do container quanto em nosso sistema.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wn4v6we9qghx9peqvrnu.png)    
* Esse tipo de Volume não é um volume criado pelo próprio Docker, ou seja, fazemos uma referência do caminho absoluto do nosso sistema para o diretório 'my-app-docker' dentro do nosso container.  

## 4. Volume  (Gerenciado pelo Docker)  
* Exemplo de uso  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;docker run -it \&lt;br&gt;
-v /my-app-docker \&lt;br&gt;
ubuntu:20.04  &lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* Nesse caso, o Docker cria um volume automaticamente dentro do nosso sistema e faz essa referência para o diretório 'my-app-docker' dentro do nosso container.  

##### Para exemplificar o uso

1. Criamos o container.
  * ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yuysvp4aai0buu3ojhw.png)
2. Executamos o comando **docker inspect id_container** para inspecionarmos as configurações do nosso container . 
  * `docker inspect 1ba5ab5ab9e0`
3. Procuramos pelo atributo **Mounts** e em seguida o **Source** para descobrirmos o caminho do diretório que o Docker criou em nosso sistema para gerenciar o volume.
  * ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bb40bh314p12e15371oh.png)
4. Copiamos o caminho do diretório e logamos como **sudo** (por conta do caminho ser protegido), logo em seguida acessamos o diretório.
  * Por eu estar utilizando o **wsl2 (ambiente linux dentro do windows)** para exemplificar esse tipo de volume, o caminho do volume criado pelo Docker fica em um caminho diferente do que é listado no **Mounts &amp;gt; Source**, caso você não esteja utilizando o **wsl2** basta acessar o caminho exibido no **Mounts &amp;gt; Source** normalmente.  
  * **Exemplo do caminho com wsl2**
      * `cd \\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes`
      * `cd 1ba0860040f23624cb8efbbfde2f53af0b1d00c4af9d588299427b096ac17696`
      * `cd .\_data\`
  * **Exemplo do caminho para ambientes linux comuns**
      * `cd/var/lib/docker/volumes/7e5cc9339921d493553691db46fceed61f89d9cc60abf6b2c1060811166a0c4d/_data`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qu0iqnho3o80vlcmxwk.png)
5. Criamos um arquivo dentro do diretório do nosso sistema e listamos esse arquivo no container.
  * `echo "Volume Gerenciado pelo Docker!" &amp;gt; volume-gerenciado-docker.txt`
  * Para criar um arquivo no linux basta digitar `touch arquivo.txt`. No exemplo acima o arquivo foi criado a partir do powershell do windows por conta da utilização do wsl2.

## 5. Diferença entre Bind-mount e Volume  
O **Bind-mount** faz uma referência a um **caminho absoluto** do nosso sistema, ou seja, nos permite escolher qual diretório queremos mapear ao docker, por conta disso ficamos "reféns" da estrutura de diretórios.
No formato Volume, o Docker faz esse trabalho, com isso abrimos um leque de possibilidades para utilizarmos os comandos que o mesmo disponibiliza, como por exemplo, create, inspect, rm, prune e etc.

## 6. Volume Nomeado (Gerenciado pelo Docker)
* Exemplo de uso  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;docker run -it \&lt;br&gt;
-v my-volume-docker:/my-app-docker \&lt;br&gt;
ubuntu:20.04&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* Crie um volume através do comando do Docker.  
  * `docker volume create my-volume-docker`  
* Execute o container através do comando do exemplo de uso.  
* Para encontrar seu volume nomeado que foi criado (my-volume-docker) acesse o diretório `/var/lib/docker/volumes`, caso esteja utilizando o **wsl2** seu volume será encontrado no diretório `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes`.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6qp63y3upc19wy9wk6z.png)
* Em seguida crie um arquivo dentro desse diretório e faça a listagem do mesmo no seu container, pronto, seu arquivo estará lá para ser acessado.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shrdtol5xrmlcwmwepys.png)

## 7. Volume Temporário (Esse tipo de volume funciona apenas no Linux)  
* Exemplo de uso
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;docker run -it \&lt;br&gt;
--tmpfs /my-app-docker \&lt;br&gt;
ubuntu:20.04&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* Enquanto nosso container estiver sendo executado, esse volume estará sendo armazenado na nossa **memória RAM**, ou seja, será um acesso mais **rápido** ao volume porém **volátil**, **não teremos uma persistência de dados** envolvida nesse método.  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2zx2kdk1hfz4b6wb78b.png)

## 8. Recomendações Docker
* Por conta de facilitar o entendimento na hora da leitura do comando, é recomendando pelo próprio Docker utilizar a flag **--mount** ao invés da flag **-v**.
* Exemplo do comando com a flag **--mount**  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;docker run -it \&lt;br&gt;
--mount type=bind,source=/home/devlmoreno/docker-volumes/my-folder-bind,target=/my-app-docker \&lt;br&gt;
ubuntu:20.04&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sxztfmvb1m0ngv3lmwxd.png)  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xd4zhsx1dkod0zb9m12l.png)  
* Estrutura do comando com a flag.
  * type = **bind** | **volume (default)** | **tmpfs**  
  * source = **diretório do nosso sistema**  
  * target = **diretório dentro do container**  
* No caso do type tmpfs, **não teríamos um source**, basta retirar esse parâmetro do comando.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;docker run -it \&lt;br&gt;
--mount type=tmpfs,target=/my-app-docker \&lt;br&gt;
ubuntu:20.04&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z9sxm5xia4t11c4o1g7z.png)  
* No caso de um volume nomeado, seguindo nosso exemplo anterior e assumindo que você criou o volume a partir do gerenciamento do Docker, podemos utilizar o comando dessa forma.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;docker run -it \&lt;br&gt;
--mount source=my-volume-docker,target=/my-app-docker \&lt;br&gt;
ubuntu:20.04&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  * Nota-se que no comando nós não passado o type, isso por conta do valor **default** do type ser **volume**.  

## 9. Documentação Docker sobre Volumes
* https://docs.docker.com/storage/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>docker</category>
      <category>volume</category>
    </item>
  </channel>
</rss>
