<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Ana Bastos Dev]]></title><description><![CDATA[Ana Bastos Dev]]></description><link>https://blog.anabastos.me</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1611188635086/MInJX-zZx.png</url><title>Ana Bastos Dev</title><link>https://blog.anabastos.me</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 19 May 2026 19:52:08 GMT</lastBuildDate><atom:link href="https://blog.anabastos.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Manual da Recursão JavaScript & Tail Call Optimization]]></title><description><![CDATA[Você já tentou escrever uma função recursiva em JavaScript e se deparou com o erro:
RangeError: Maximum call stack size exceeded

Isso acontece porque o JavaScript não implementa Tail Call Optimization (TCO) — um recurso previsto na especificação do ...]]></description><link>https://blog.anabastos.me/manual-da-recursao-javascript-and-tail-call-optimization</link><guid isPermaLink="true">https://blog.anabastos.me/manual-da-recursao-javascript-and-tail-call-optimization</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[Recursion in programming ]]></category><category><![CDATA[recursion in javascript]]></category><dc:creator><![CDATA[Ana Luiza Portello Bastos]]></dc:creator><pubDate>Wed, 14 May 2025 17:26:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1747243559579/e0c72917-7cb6-4c3b-a05c-e6c44a37987a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<p>Você já tentou escrever uma função recursiva em JavaScript e se deparou com o erro:</p>
<pre><code class="lang-plaintext">RangeError: Maximum call stack size exceeded
</code></pre>
<p>Isso acontece porque o JavaScript <strong>não implementa Tail Call Optimization (TCO)</strong> — um recurso previsto na especificação do ECMAScript 2015 (ES6), mas nunca adotado pelos principais motores.</p>
<p>Antes de entender o problema, vamos entender a base.</p>
<hr />
<h3 id="heading-o-que-e-recursao">O que é recursão?</h3>
<p><strong>Recursão</strong> acontece quando uma função chama a si mesma — direta ou indiretamente. Toda recursão precisa de duas partes:</p>
<ul>
<li><p><strong>Caso base (condição de saída)</strong>: quando parar de chamar a si mesma;</p>
</li>
<li><p><strong>Chamada recursiva</strong>: onde a função se chama com um argumento diferente, normalmente em direção ao caso base.</p>
</li>
</ul>
<h3 id="heading-exemplo-classico">Exemplo clássico:</h3>
<pre><code class="lang-plaintext">function countDown(n) {
  if (n === 0) return;
  console.log(n);
  countDown(n - 1); // chamada recursiva
}
</code></pre>
<p>Sem um caso base (<code>if (n === 0) return</code>), essa função entraria em loop infinito, até estourar a pilha de chamadas.</p>
<hr />
<h3 id="heading-tipos-comuns-de-recursao">Tipos comuns de recursão</h3>
<p>Além da <strong>recursão direta</strong> (uma função chama a si mesma), existem:</p>
<ul>
<li><strong>Recursão indireta</strong>: a função A chama B, que chama A novamente.</li>
</ul>
<pre><code class="lang-plaintext">function isEven(n) {
  if (n === 0) return true;
  return isOdd(n - 1);
}

function isOdd(n) {
  if (n === 0) return false;
  return isEven(n - 1);
}
</code></pre>
<ul>
<li><strong>Recursão mútua</strong>: dois ou mais métodos se chamam em um ciclo.</li>
</ul>
<pre><code class="lang-plaintext">function A(n) {
  if (n &lt;= 0) return;
  console.log("A", n);
  B(n - 1);
}

function B(n) {
  if (n &lt;= 0) return;
  console.log("B", n);
  C(n - 1);
}

function C(n) {
  if (n &lt;= 0) return;
  console.log("C", n);
  A(n - 1);
}
</code></pre>
<ul>
<li><strong>Recursão de cauda (tail recursion)</strong>: a chamada recursiva é a última instrução da função.</li>
</ul>
<p>Essa última é a mais importante para performance, pois é onde a <strong>Tail Call Optimization</strong> pode atuar.</p>
<hr />
<h3 id="heading-como-funciona-a-stack-no-javascript">Como funciona a stack no JavaScript?</h3>
<p>Quando você chama uma função em JavaScript, o motor de execução cria um <strong>stack frame</strong> (quadro de pilha) contendo:</p>
<ul>
<li><p>Onde retornar quando a função acabar;</p>
</li>
<li><p>O escopo local da função;</p>
</li>
<li><p>Parâmetros e variáveis locais.</p>
</li>
</ul>
<p>Cada chamada recursiva empilha mais um frame. Quando a base do caso recursivo é finalmente atingida, o motor do JS começa a desempilhar tudo. Se houver muitas chamadas antes de atingir esse ponto, a pilha explode.</p>
<p>Se houver chamadas demais antes de chegar no fim, você verá:</p>
<pre><code class="lang-plaintext">RangeError: Maximum call stack size exceeded
</code></pre>
<h3 id="heading-o-que-e-tail-call-optimization">O que é Tail Call Optimization?</h3>
<p>Tail Call Optimization é uma técnica em que o interpretador ou compilador percebe que <strong>a última coisa que uma função precisa fazer antes de retornar é chamar outra função</strong>. Em vez de adicionar um novo frame na pilha de chamadas (call stack), ele <strong>reutiliza</strong> o frame atual.</p>
<h3 id="heading-exemplo-sem-tco-chamada-recursiva-tradicional">Exemplo sem TCO (chamada recursiva tradicional)</h3>
<pre><code class="lang-plaintext">function factorial(n) {
  if (n &lt; 2) return 1;
  return n * factorial(n - 1); // NÃO é tail call
}
</code></pre>
<p>Essa função é recursiva, mas o valor de <code>factorial(n - 1)</code> ainda precisa ser multiplicado por <code>n</code> depois de resolvido. Logo, a chamada não está na <strong>posição final</strong> da função (tail position), e a stack cresce a cada chamada.</p>
<h3 id="heading-tail-recursive">Tail-recursive</h3>
<p>Aqui, a última instrução da função <code>fact</code> é a chamada recursiva. Com TCO, seria possível rodar isso de forma tão eficiente quanto um <code>for</code> ou <code>while</code>, porque a pilha não cresceria.</p>
<pre><code class="lang-plaintext">function factorial(n) {
  function fact(n, acc) {
    if (n &lt; 2) return acc;
    return fact(n - 1, n * acc); // &lt;- chamada em posição de cauda
  }
  return fact(n, 1);
}
</code></pre>
<hr />
<h3 id="heading-a-promessa-do-es6-e-do-es8">A promessa do ES6 (e do ES8)</h3>
<p>A especificação do ES6 prometia suporte a TCO. E mais: ela <strong>exigia</strong> que os motores JavaScript fizessem otimização de chamadas em tail position em modo <em>strict</em> (<code>'use strict'</code>).</p>
<p>Já o ES8 (2017) trouxe <code>async/await</code>, que ajudou a tratar recursões assíncronas — mas não resolveu o problema da pilha em recursões síncronas.</p>
<h3 id="heading-exemplo-de-recursao-perigosa">Exemplo de recursão perigosa:</h3>
<pre><code class="lang-plaintext">function pow(base, power) {
  if (power === 0) return 1;
  return pow(base, power - 1) * base;
}
pow(4, 84599); // Em inputs altos ele estoura 💥
</code></pre>
<h3 id="heading-mas-por-que-javascript-ignorou-a-especificacao">Mas… por que JavaScript ignorou a especificação?</h3>
<p>Apesar de TCO estar na especificação do ECMAScript 2015 (ES6) — com a exigência de suporte em modo <code>'use strict'</code> — <strong>nenhum dos principais motores de JavaScript modernos implementou</strong>.</p>
<h3 id="heading-teorias-e-motivos">Teorias e motivos:</h3>
<ol>
<li><p><strong>Compatibilidade com depuradores</strong><br />  Ferramentas de debug como o Chrome DevTools se baseiam na pilha tradicional. Otimizar frames quebraria o rastreamento entre chamadas.</p>
</li>
<li><p><strong>Complexidade de implementação</strong><br />  Motores como o V8 (Chrome e Node.js) foram otimizados para desempenho em outras áreas. Suportar TCO exigiria reestruturações profundas.</p>
</li>
<li><p><strong>Baixo uso prático</strong><br />  Como loops são mais comuns no ecossistema JavaScript, o esforço para suportar TCO não se justifica.</p>
</li>
<li><p><strong>Efeito dominó de compatibilidade</strong><br />  Se apenas um motor suportar TCO e os outros não, surgem inconsistências. Como nenhum quis ser o primeiro, nenhum implementou.</p>
</li>
</ol>
<p>Atualmente, apenas o Safari (WebKit) chegou a oferecer algum suporte a TCO, mas até isso foi limitado e eventualmente descontinuado.</p>
<p>Em resumo: <em>JavaScript ignorou TCO porque isso traria mais problemas (e custos) do que soluções no ecossistema atual</em>.</p>
<hr />
<h3 id="heading-recursao-assincrona-com-asyncawait">Recursão assíncrona com <code>async/await</code></h3>
<p>Recursão assíncrona contorna o problema de stack overflow porque <strong>cada chamada aguarda o término da anterior</strong> antes de continuar, liberando a stack.</p>
<pre><code class="lang-plaintext">async function processItems(items, index = 0) {
  if (index &gt;= items.length) return;
  await doSomething(items[index]);
  return processItems(items, index + 1);
}
</code></pre>
<p>Essa abordagem é <strong>segura para longas listas</strong> ou processos de IO.</p>
<hr />
<h3 id="heading-alternativas-praticas">Alternativas práticas</h3>
<p>Se você precisa de segurança e performance:</p>
<ul>
<li><p>Use <code>for</code> ou <code>while</code> no lugar de recursão tradicional;</p>
</li>
<li><p>Se for usar recursão, prefira a forma tail-recursive;</p>
</li>
<li><p>Use <code>async/await</code> para recursão que lida com IO assíncrono;</p>
</li>
<li><p>Evite recursões profundas em funções síncronas.</p>
</li>
</ul>
<p>O livro <em>Eloquent JavaScript</em> já alerta:</p>
<blockquote>
<p><em>“Em JavaScript, executar um loop simples é muito mais barato do que chamar uma função múltiplas vezes. A recursão eficiente exige suporte à eliminação de chamadas em cauda.”</em></p>
</blockquote>
<p>Em benchmarks, loops são <strong>até 10x mais rápidos</strong> do que recursão em JavaScript.</p>
<hr />
<h3 id="heading-por-que-linguagens-funcionais-usam-tanta-recursao">Por que linguagens funcionais usam tanta recursão?</h3>
<p>Embora loops (<code>for</code>, <code>while</code>) sejam frequentemente usados no lugar da recursão em linguagens como JavaScript por questões de performance e controle da stack, eles <strong>não substituem a recursão conceitualmente</strong> — apenas imitam certos comportamentos.</p>
<p>A recursão expressa um <strong>paradigma funcional</strong>, onde o fluxo do programa é descrito em termos de <strong>chamadas de função</strong>, e não de iteração explícita. Isso permite representar problemas complexos de forma mais declarativa, como árvores, grafos e algoritmos matemáticos elegantes. Substituir recursão por loops é, na prática, uma <strong>mudança de paradigma de programação</strong>, que pode reduzir clareza e expressividade dependendo do caso.</p>
<p>Linguagens como Haskell, Elixir ou Scheme evitam loops imperativos. Nelas, recursão é a forma natural de repetição.</p>
<p>E o principal: <strong>elas implementam TCO de verdade</strong>. Isso significa que chamadas recursivas são otimizadas pelo compilador, sem riscos de stack overflow.</p>
<h3 id="heading-conclusao">Conclusão</h3>
<p>Recursão é poderosa, mas perigosa em JavaScript sem suporte a TCO. Linguagens funcionais mostram o potencial real da recursão com suporte de verdade do compilador. Até lá, o JavaScript exige cuidados extra especialmente se você estiver pensando em escrever sem uma boa razão.</p>
<p>Se precisar da performance e segurança de uma stack estável, prefira <code>for</code>, <code>while</code> ou <code>async/await</code>. E se for usar recursão, prefira sempre que possível a forma tail-recursive — ainda que o motor JS não otimize, seu código será mais claro, testável e portável.</p>
<hr />
<h3 id="heading-referencias">Referências</h3>
<ul>
<li><p><a target="_blank" href="https://eloquentjavascript.net/">Eloquent JavaScript, 3rd Edition</a></p>
</li>
<li><p>Tail Call Optimization in ES6 (2ality)</p>
</li>
<li><p><a target="_blank" href="https://kangax.github.io/compat-table/es6/">ES6 Compatibility Table (Kangax)</a></p>
</li>
<li><p><a target="_blank" href="https://blog.scottlogic.com/">Async recursion in JavaScript (Scott Logic)</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Como criar um README.md pessoal no github]]></title><description><![CDATA[O README.md já era um arquivo essencial para documentação de projetos, mas agora ele também pode ser utilizado para apresentar quem você é no GitHub. Com a possibilidade de fixá-lo no perfil, podemos ser criativos e transformar esse arquivo em um ver...]]></description><link>https://blog.anabastos.me/como-criar-um-readmemd-pessoal-no-github</link><guid isPermaLink="true">https://blog.anabastos.me/como-criar-um-readmemd-pessoal-no-github</guid><category><![CDATA[technology]]></category><category><![CDATA[README]]></category><category><![CDATA[markdown]]></category><dc:creator><![CDATA[Ana Luiza Portello Bastos]]></dc:creator><pubDate>Fri, 14 Mar 2025 16:43:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1741970826911/3af0069d-0ace-4786-b79d-70abedec4587.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<p>O README.md já era um arquivo essencial para documentação de projetos, mas agora ele também pode ser utilizado para apresentar quem você é no GitHub. Com a possibilidade de fixá-lo no perfil, podemos ser criativos e transformar esse arquivo em um verdadeiro portfólio interativo.</p>
<p>Neste artigo, vamos explorar algumas ideias e dicas para você criar um README.md pessoal que realmente se destaque!</p>
<hr />
<h3 id="heading-1-formatacao-basica">1. Formatação Básica</h3>
<p>O Github na verdade tem um markdown proprio chamado <a target="_blank" href="https://github.github.com/gfm/">GitHub Flavored Markdown (GFM)</a>, que é basicamente um markdown with steroids.</p>
<p>Você pode checar a documentação aqui <a target="_blank" href="https://github.github.com/gfm/">https://github.github.com/gfm/</a></p>
<p>Mas além disso, você ainda pode usar HTML dentro do seu markdown, o que possíbilita modificar tamanho de imagem e o alinhamento dos elementos.</p>
<p>MAS ainda assim o markdown é bem sanitizado pelo github o que faz com que boa parte das propriedades e tags não funcionem principalmente a tag <code>style</code> que possibilitaria colocar estilos mais dinamicamente 😢</p>
<p>Algumas tags possíveis são: <code>address</code>, <code>article</code>, <code>aside</code>, <code>base</code>, <code>basefont</code>, <code>blockquote</code>, <code>body</code>, <code>caption</code>, <code>center</code>, <code>col</code>, <code>colgroup</code>, <code>dd</code>, <code>details</code>, <code>dialog</code>, <code>dir</code>, <code>div</code>, <code>dl</code>, <code>dt</code>, <code>fieldset</code>, <code>figcaption</code>, <code>figure</code>, <code>footer</code>, <code>form</code>, <code>frame</code>, <code>frameset</code>, <code>h1</code>, <code>h2</code>, <code>h3</code>, <code>h4</code>, <code>h5</code>, <code>h6</code>, <code>head</code>, <code>header</code>, <code>hr</code>, <code>html</code>, <code>iframe</code>, <code>legend</code>, <code>li</code>, <code>link</code>, <code>main</code>, <code>menu</code>, <code>menuitem</code>, <code>nav</code>, <code>noframes</code>, <code>ol</code>, <code>optgroup</code>, <code>option</code>, <code>p</code>, <code>param</code>, <code>section</code>, <code>source</code>, <code>summary</code>, <code>table</code>, <code>tbody</code>, <code>td</code>, <code>tfoot</code>, <code>th</code>, <code>thead</code>, <code>title</code>, <code>tr</code>, <code>track</code>, <code>ul</code> .</p>
<p>Essa limitação deixa aberto para sermos criativos em que elementos vamos usar!!</p>
<h4 id="heading-headers">Headers</h4>
<pre><code class="lang-plaintext"># Sou uma tag `&lt;h1&gt;`
## Sou uma tag `&lt;h2&gt;`
###### Sou uma tag `&lt;h6&gt;`
</code></pre>
<h4 id="heading-destaques-de-texto">Destaques de Texto</h4>
<pre><code class="lang-plaintext">*Texto em itálico*
**Texto em negrito**
~~Texto riscado~~
</code></pre>
<h4 id="heading-citacoes">Citações</h4>
<pre><code class="lang-plaintext">&gt; Isso é uma citação
</code></pre>
<h4 id="heading-divisorias">Divisórias</h4>
<h4 id="heading-listas">Listas</h4>
<pre><code class="lang-plaintext">Tecnologias que eu mais gosto
  - Python
  - Javascript
    - React
</code></pre>
<h4 id="heading-codigo">Código</h4>
<pre><code class="lang-plaintext">// Bloco de código
```
const name = "Ana Luiza";
```

// ou inline
`const age = 29`
</code></pre>
<h4 id="heading-links-e-imagens">Links e Imagens</h4>
<pre><code class="lang-plaintext">[Texto do Link](https://www.exemplo.com)
![Texto Alternativo](https://github.githubassets.com/images/modules/profile/badge--acv-64.png)
</code></pre>
<h4 id="heading-tabelas">Tabelas</h4>
<p>Voce pode usar tabelas para descrever também experiencias, ferramentas e skills.</p>
<p><img src="https://cdn-images-1.medium.com/max/788/1*H7YiDpoLgHJRRtJoM-n7kw.png" alt /></p>
<p><a target="_blank" href="https://github.com/sw9brl">https://github.com/sw9brl</a> em 24/08/2020</p>
<p>Mais sobre formatação: <a target="_blank" href="https://guides.github.com/features/mastering-markdown/">Mastering Markdown</a></p>
<hr />
<h3 id="heading-2-o-que-incluir-no-seu-readme">2. O Que Incluir no Seu README?</h3>
<h3 id="heading-sobre-voce">Sobre Você</h3>
<ul>
<li><p>Quem você é? Onde trabalha ou estuda? O que voce se interessa? O que anda estudando? Que tipo de projetos voce costuma colaborar? Qual sua stack? Está procurando por emprego ou freelance? O que anda estudando? Qual seu objetivo?</p>
</li>
<li><p>FAQ, Curriculo, Experiencias de trabalho, Projetos pessoais, interesses, quais seus valores, tecnologias que voce usa, como voce costuma trabalhar?</p>
</li>
</ul>
<h3 id="heading-exemplos-de-estrutura">Exemplos de Estrutura:</h3>
<h4 id="heading-caracteristicas-sobre-mim">Características Sobre Mim</h4>
<pre><code class="lang-plaintext">- 🔭 Trabalhando atualmente em projetos open source
- 🌱 Aprendendo mais sobre DevOps e Cloud
- 💬 Me pergunte sobre React, Golang e banco de dados
</code></pre>
<h4 id="heading-tecnologias-que-eu-mais-gosto">Tecnologias Que Eu Mais Gosto</h4>
<pre><code class="lang-plaintext">- 🖥️ Backend: Golang, Node.js
- 🎨 Frontend: React, Vue
- 🗄️ Banco de Dados: PostgreSQL, MongoDB
</code></pre>
<h4 id="heading-objetivos-2024">Objetivos 2024</h4>
<pre><code class="lang-plaintext">- [x] Contribuir para um projeto open source
- [ ] Criar meu próprio curso online
</code></pre>
<hr />
<h3 id="heading-3-como-deixar-seu-readme-mais-interativo">3. Como Deixar Seu README Mais Interativo</h3>
<h4 id="heading-adicionar-videos">Adicionar Videos</h4>
<p>O readme.md não suporta videos, MAS suporta tags <code>a</code>, então podemos linkar o embbeded do video ao video em si.</p>
<pre><code class="lang-plaintext">&lt;a href="http://www.youtube.com/watch?feature=player_embedded&amp;v=ID_DO_VIDEO
" target="_blank"&gt;&lt;img src="http://img.youtube.com/vi/ID_DO_VIDEO/0.jpg" 
alt="IMAGE ALT TEXT HERE" width="240" height="180" border="10" /&gt;&lt;/a&gt;
</code></pre>
<h4 id="heading-emojis">Emojis 😎</h4>
<p>Adicione emojis para dar mais personalidade ao seu README! Use <code>:emoji:</code> para inserir emojis.</p>
<p>Aqui tem um cheat sheet com todos os emojis!</p>
<p><a target="_blank" href="https://github.com/ikatyang/emoji-cheat-sheet/blob/master/README.md"><strong>emoji-cheat-sheet/README.md at master · ikatyang/emoji-cheat-sheet</strong><br /><em>A markdown version emoji cheat sheet. Contribute to ikatyang/emoji-cheat-sheet development by creating an account on…</em>github.com</a></p>
<h4 id="heading-badges">Badges 🏆</h4>
<p>Use <a target="_blank" href="https://shields.io/">Shields.io</a> para criar badges personalizados:</p>
<pre><code class="lang-plaintext">![GitHub followers](https://img.shields.io/github/followers/seuusuario?style=social)
</code></pre>
<p>O <a target="_blank" href="https://www.codewars.com/users/jhoffner/badges">codewars</a> também disponibiliza badges para mostrar sua pontuação na ferramenta.</p>
<p>Se voce costuma colaborar com o open source nada mais justo do que deixar claro como as pessoas podem te ajudar.</p>
<p>Faz sentindo criar links para Donates como paypal, patreon, gratipay etc.</p>
<p><img src="https://cdn-images-1.medium.com/max/788/0*Bu9oZ14MQwG2qNWl" alt /></p>
<p><img src="https://cdn-images-1.medium.com/max/591/0*EgggNnUk9AsUc48s.jpg" alt /></p>
<p><a target="_blank" href="https://github.com/Naereen/badges"><strong>GitHub — Naereen/badges: Markdown code for lots of small badges (shields.io, forthebadge.com etc) …</strong><br /><em>pencil: Markdown code for lots of small badges :ribbon: :pushpin: (shields.io, forthebadge.com etc) :sunglasses…</em>github.com</a></p>
<h4 id="heading-estatisticas">Estatísticas 📊</h4>
<p>Use <a target="_blank" href="https://github.com/anuraghazra/github-readme-stats">GitHub Readme Stats</a> para mostrar suas estatísticas automaticamente:</p>
<pre><code class="lang-plaintext">![Estatísticas do GitHub](https://github-readme-stats.vercel.app/api?username=seuusuario&amp;show_icons=true)
</code></pre>
<h3 id="heading-gifs-e-imagens-customizadas">Gifs e Imagens Customizadas 🎨</h3>
<p>Crie ilustrações, icones ou gifs personalizados e adicione ao seu README:</p>
<h4 id="heading-gifs">Gifs</h4>
<p>Algumas dicas:</p>
<ul>
<li>Use <a target="_blank" href="http://recordit.co/">Recordit</a> para criar gravações de tela do seu desktop e exporte como <code>GIF</code>s.</li>
</ul>
<p><img src="https://cdn-images-1.medium.com/max/788/0*g9XeWVTKuYlMM-Zs" alt /></p>
<p>Gravação da sua tela</p>
<ul>
<li>Voce também pode gravar sua sessão no terminal com o <a target="_blank" href="https://github.com/chjj/ttystudio">ttystudio</a> que também suporta exportar para<code>GIF</code>s.</li>
</ul>
<p><img src="https://cdn-images-1.medium.com/max/788/0*u0RI5LLCUxyCaeN-.gif" alt /></p>
<p>Gravação do terminal</p>
<ul>
<li>No giphy ao clicar no “ Stickers” você consegue achar gifs com fundo transparente.</li>
</ul>
<h4 id="heading-imagens">Imagens</h4>
<p>A maneira mais segura de manter os arquivos é criar uma pasta <em>screenshots</em>, <em>github</em>, <em>assets</em>, <em>resources</em> ou nome que você quiser e deixar os arquivos nela. Se você usar um CDN de imagens ou gif pode funcionar mas corre o risco do quebrar o link algum dia.</p>
<p>Usar a tag <code>img</code> do html possíbilita que possamos dinamizar um pouco mais as imgs.</p>
<p>Supondo que você tenha criado uma pasta <em>assets</em> no seu projeto e tem o arquivo <em>banner.png</em>, é assim que você pode adicionar a imagem:</p>
<pre><code class="lang-plaintext">&lt;h1 align="center"&gt;
  &lt;img alt="NextLevelWeek" title="#NextLevelWeek" src="./assets/banner.png" /&gt;
&lt;/h1&gt;
</code></pre>
<p>Com o align center a imagem fica centralizada</p>
<p>Podemos editar o tamanho das imagens também se usarmos a tag</p>
<pre><code class="lang-plaintext">&lt;img align="right" height="200" src="https://github.com/rajput2107/rajput2107/blob/master/Assets/Developer.gif"/&gt;
</code></pre>
<p>Alguns exemplos legais são de githubs que criaram ilutrações legais deles mesmos para personalizar o readme.md:</p>
<p><img src="https://cdn-images-1.medium.com/max/591/1*qpwOT3CHA73E9teaJ8KWtQ.png" alt /></p>
<p><img src="https://cdn-images-1.medium.com/max/394/1*vayY16KxHQXdfKeywUWfLg.png" alt /></p>
<p><img src="https://cdn-images-1.medium.com/max/591/1*kBUBuK5Aa28MHYbpGz448Q.gif" alt /></p>
<p>Alguns exemplos legais de ilustrações de si mesmo</p>
<p>Com isso podemos também colocar icones que linkem para nossas redes sociais ou para tecnologias que gostamos</p>
<p>Ou então hospedar os slides em algum lugar e postar apenas a primeira pagina deles.</p>
<pre><code class="lang-plaintext">&lt;img align="right" height="200" src="https://github.com/rajput2107/rajput2107/blob/master/Assets/Developer.gif"/&gt;
</code></pre>
<p>Para usar icones ou ilustrações use ferramentas como:</p>
<ul>
<li><p><a target="_blank" href="https://www.flaticon.com/">Flaticon</a></p>
</li>
<li><p><a target="_blank" href="https://simpleicons.org/">Simple Icons</a></p>
</li>
<li><p><a target="_blank" href="https://www.canva.com/pt_br/criar/logotipo/">Canva</a></p>
</li>
</ul>
<h4 id="heading-redes-sociais">Redes Sociais 🌍</h4>
<pre><code class="lang-plaintext">[![LinkedIn](https://img.shields.io/badge/LinkedIn-blue?style=flat-square&amp;logo=linkedin)](https://www.linkedin.com/in/seuusuario)
[![Twitter](https://img.shields.io/badge/Twitter-blue?style=flat-square&amp;logo=twitter)](https://twitter.com/seuusuario)
</code></pre>
<h4 id="heading-tecnologias-e-ferramentas">Tecnologias e Ferramentas 🛠️</h4>
<pre><code class="lang-plaintext">![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=flat-square&amp;logo=typescript&amp;logoColor=white)
![Python](https://img.shields.io/badge/Python-3776AB?style=flat-square&amp;logo=python&amp;logoColor=white)
![Java](https://img.shields.io/badge/Java-007396?style=flat-square&amp;logo=java&amp;logoColor=white)
![Golang](https://img.shields.io/badge/Go-00ADD8?style=flat-square&amp;logo=go&amp;logoColor=white)
</code></pre>
<p><img src="https://cdn-images-1.medium.com/max/788/1*AKKd8S1lNGZkLlGoWMnDHA.png" alt /></p>
<p><a target="_blank" href="https://github.com/Sancho41?fbclid=IwAR1PgBrrEZmx0Kys3fvG2lm0kp_PZa_vj0mEIypdsHYY-lD8LChh1EZue1k">https://github.com/Sancho41</a></p>
<h3 id="heading-projetos-em-destaque">Projetos em Destaque 🚀</h3>
<p>Destaque seus melhores repositórios:</p>
<pre><code class="lang-plaintext">[![Repo](https://github-readme-stats.vercel.app/api/pin/?username=seuusuario&amp;repo=seurepo)](https://github.com/seuusuario/seurepo)
</code></pre>
<h3 id="heading-4-dicas-extras-para-seo">4. Dicas Extras para SEO</h3>
<ul>
<li><p>Adicione palavras-chave relacionadas ao seu nicho</p>
</li>
<li><p>Inclua seu nome completo em texto</p>
</li>
<li><p>Linke para redes sociais, portfólio e projetos</p>
</li>
<li><p>Atualize regularmente</p>
</li>
</ul>
<hr />
<h3 id="heading-conclusao">Conclusão 🎯</h3>
<p>O README.md do seu perfil no GitHub é uma grande oportunidade de destacar suas habilidades, experiências e paixões. Personalize-o, torne-o único e mostre ao mundo o que você sabe fazer!</p>
<p>E aí, pronto para atualizar o seu? 🚀</p>
]]></content:encoded></item><item><title><![CDATA[Como Dar Palestras de Tecnologia 🎤💻]]></title><description><![CDATA[O Que é Dar uma Palestra e Para Que Serve? 🤔
Se fosse apenas para ler documentação, ninguém precisaria assistir a uma palestra! O objetivo principal de uma apresentação não é fazer com que as pessoas saiam sabendo 100% do conteúdo, até porque ningué...]]></description><link>https://blog.anabastos.me/como-dar-palestras-de-tecnologia</link><guid isPermaLink="true">https://blog.anabastos.me/como-dar-palestras-de-tecnologia</guid><category><![CDATA[technology]]></category><category><![CDATA[Speakers]]></category><category><![CDATA[#techtalks]]></category><dc:creator><![CDATA[Ana Luiza Portello Bastos]]></dc:creator><pubDate>Fri, 14 Mar 2025 16:37:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1741970973411/36489fc6-4fda-4a89-bfcd-799a852bae84.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-o-que-e-dar-uma-palestra-e-para-que-serve"><strong>O Que é Dar uma Palestra e Para Que Serve? 🤔</strong></h1>
<p>Se fosse apenas para ler documentação, ninguém precisaria assistir a uma palestra! O objetivo principal de uma apresentação não é fazer com que as pessoas saiam sabendo 100% do conteúdo, até porque ninguém consegue absorver tudo de uma vez. O foco deve ser:</p>
<p>✅ Que as pessoas entendam minimamente sobre o assunto e sua proposta. ✅ Que despertem interesse ou não pelo tema.<br />✅ Que saibam onde buscar mais informação caso queiram aprofundar.<br />✅ Que compreendam como o conteúdo pode ser aplicado em seus desafios profissionais.</p>
<h1 id="heading-conteudo"><strong>Conteúdo 📚🎯</strong></h1>
<p>A ideia principal é transformar teoria em algo palpável!</p>
<p>Simplesmente repetir documentação só faz sentido se você for explicar de uma forma diferente ou mais acessível. As palestras ajudam a tornar o conteúdo mais tangível, e conectar conceitos teóricos com casos reais sempre funciona melhor. Algumas dicas:</p>
<p>🚀 Tecnologias novas ou de nicho são instigantes e incentivam as pessoas a explorarem mais.</p>
<p>🧐 Mostrar o conteúdo para amigos da área antes da palestra pode ajudar a identificar dúvidas comuns.</p>
<p>🙌 Palestras superficiais também têm valor! Elas dão acessibilidade para quem ainda não conhece o tema.</p>
<p>📝 Tenha certeza de que você realmente domina o assunto e que seu conteúdo é relevante.</p>
<h1 id="heading-ferramentas-para-criar-apresentacoes"><strong>🎨 Ferramentas para Criar Apresentações</strong></h1>
<p>Uma forma simples e prática de criar apresentações é usando o <strong>Google Slides</strong>. Ele permite:</p>
<p>✅ Criar e organizar slides rapidamente.<br />✅ Adicionar notas de apresentação.<br />✅ Criar animações.<br />✅ Compartilhar com organizadores e colaboradores para revisão e feedback.</p>
<p>Mas existem outras opções bem interessantes, dependendo do seu estilo:</p>
<p>🚀 <strong>Marp</strong> — Markdown + slides bonitos com suporte a código.<br />🌐 <strong>Reveal.js</strong> — Framework HTML para criar slides interativos com syntax highlighting.<br />🍏 <strong>Deckset (Mac)</strong> — Transforma Markdown em apresentações, ótimo para desenvolvedores.<br />📜 <strong>Beamer (LaTeX)</strong> — Para apresentações acadêmicas sofisticadas.<br />🖥️ <strong>LibreOffice Impress</strong> — Alternativa open-source ao PowerPoint.<br />📝 <strong>Org-mode (Emacs)</strong> — Permite criar apresentações diretamente no Emacs, ideal para quem já usa essa ferramenta.</p>
<p>Se você gosta de ferramentas mais dinâmicas, pode explorar:</p>
<p>💡 <strong>Pitch</strong> — Apresentações colaborativas e modernas.<br />🎭 <strong>Prezi</strong> — Apresentações não-lineares e dinâmicas.<br />⚡ <strong>Canva</strong> — Opção visualmente rica e fácil de usar.</p>
<h1 id="heading-textos"><strong>💬 Textos</strong></h1>
<p>Ninguém quer ler um monte de texto durante uma palestra, até porque, se fosse para ler, seria mais fácil pegar um livro! 📖</p>
<p>🔹 É muito difícil engajar pessoas com blocos enormes de texto.<br />🔹 Use <strong>bullet points</strong> apenas como guias para destacar os principais tópicos. 🔹 Explique com suas próprias palavras em vez de seguir um script fixo.<br />🔹 Se você ler um slide palavra por palavra, pode parecer que não domina o assunto.<br />🔹 O ideal é que os slides complementem a sua fala, não que sejam um teleprompter!</p>
<h1 id="heading-abusar-de-imagens-e-animacoes"><strong>🎨 Abusar de imagens e animações</strong></h1>
<p>Referências visuais sempre ajudam a manter o público engajado.</p>
<p>Sempre que possível coloque GIFs ou imagens engraçadas para manipular a reação do público ao conteúdo(mostrar surpresa, ou frustração sobre algum tema)</p>
<h1 id="heading-trechos-de-codigo"><strong>📝 Trechos de Código</strong></h1>
<ul>
<li><p>Devem ser curtos e legíveis.</p>
</li>
<li><p>Se forem complexos, mostre o passo a passo de modificação.</p>
</li>
<li><p>Nada de paredes de texto! Isso só afasta a audiência.</p>
</li>
</ul>
<p>Uma ideia é usar o <a target="_blank" href="https://carbon.now.sh/"><strong>Carbon</strong></a>, que gera imagens estilizadas de código para apresentação.</p>
<h1 id="heading-limite-sua-apresentacao"><strong>Limite Sua Apresentação ⏳</strong></h1>
<p>Claro que é legal falar um pouco sobre você, sua empresa e seu background. Mas a palestra <strong>não</strong> deve virar uma propaganda!</p>
<p>🚫 Não transforme o evento em um pitch sobre sua empresa ou sua carreira.<br />✅ Dê uma passada rápida no início ou final sobre você e pronto.<br />🎟️ Respeite o tempo do público, que pode ter investido dinheiro e tempo para aprender algo novo.</p>
<h1 id="heading-live-coding"><strong>Live Coding 💻⚡</strong></h1>
<p>Live coding é incrível, mas pode ser um grande desafio. Principalmente pois tudo que pode dar errado <strong>VAI DAR ERRADO</strong>. Algumas dicas:</p>
<p>📌 Sempre deixe uma cola com os trechos do codigo<br />📌 Funciona sem internet? Funciona se fizer o setup do zero em um computador novo? Esses imprevistos sempre surpreendem!<br />📌 Não use fontes pequenas! Use uma fonte <strong>BEM GRANDE</strong>.<br />📌 Prefira REPLs ou ferramentas interativas a apenas navegar por código estático.</p>
<h1 id="heading-ferramentas-de-apresentacao-com-suporte-a-codigo"><strong>Ferramentas de Apresentação com Suporte a Código</strong></h1>
<ol>
<li><p><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=vsls-contrib.codetour"><strong>CodeTour (VS Code)</strong></a> — Faz guias passo a passo interativos dentro do VS Code.</p>
</li>
<li><p><a target="_blank" href="https://replit.com/"><strong>Replit</strong></a> — Permite rodar e demonstrar código diretamente no navegador.</p>
</li>
<li><p><a target="_blank" href="https://jupyter.org/"><strong>Jupyter Notebooks</strong></a> — Perfeito para Python e dados, combina código e explicações no mesmo lugar.</p>
</li>
<li><p><a target="_blank" href="https://asciinema.org/"><strong>asciinema</strong></a> — Grava sessões de terminal e permite reproduzir sem medo de errar.</p>
</li>
<li><p><a target="_blank" href="https://github.com/charmbracelet/glow"><strong>Glow</strong></a> — Exibe Markdown direto no terminal, ótimo para destacar comandos.</p>
</li>
</ol>
<h1 id="heading-perguntas"><strong>Perguntas ❓💡</strong></h1>
<p>Perguntas não devem ser um motivo de medo! Algumas dicas para lidar com elas:</p>
<p>🔹 Reflita sobre o público: o que ele pode querer saber? Como pode aplicar esse conhecimento?<br />🔹 Se você não souber responder, tudo bem! É normal. Seja honesto e indique fontes para pesquisa.<br />🔹 Nenhuma resposta é “lei”! Sempre deixe claro que pode haver diferentes opiniões ou abordagens.</p>
<h1 id="heading-conclusao"><strong>Conclusão 🎯</strong></h1>
<p>Dar palestras é uma ótima forma de compartilhar conhecimento, se conectar com a comunidade e aprender mais. Com um bom planejamento, um formato envolvente e respeito pelo público, você pode transformar qualquer tema técnico em algo realmente impactante! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[A magica da arrumação das notificações do Github]]></title><description><![CDATA[Ter mais visibilidade das coisas que importam no nosso dia-a-dia pode ser um grande aliado pra melhorar nossa produtividade 👊
Recentemente tiveram atualizações que mudaram completamente a forma como lidamos com notificações no Github. Mas a maioria ...]]></description><link>https://blog.anabastos.me/a-magica-da-arrumacao-das-notificacoes-do-github</link><guid isPermaLink="true">https://blog.anabastos.me/a-magica-da-arrumacao-das-notificacoes-do-github</guid><category><![CDATA[GitHub]]></category><dc:creator><![CDATA[Ana Luiza Portello Bastos]]></dc:creator><pubDate>Thu, 21 Jan 2021 02:42:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1611199482101/M8eKL0CQx.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Ter mais visibilidade das coisas que importam no nosso dia-a-dia pode ser um grande aliado pra melhorar nossa produtividade 👊</p>
<p>Recentemente tiveram atualizações que mudaram completamente a forma como lidamos com notificações no Github. Mas a maioria das pessoas que já estavam por lá antes disso, que já não davam tanta bola para notificações, hoje tem o problema de terem uma quantia desnecessária de <strong>ruído</strong> .</p>
<p>Trocentas notificações que sequer soubemos da onde vem.</p>
<p>Isso fica pior quando você tem organizações, times, tanto de empresas quanto de projetos pessoais, open source etc que são <strong>heavy users</strong>. Eu por exemplo estava com o inbox assim:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611190588090/N8af7_q-b.png" alt="Screen Shot 2021-01-20 at 17.17.29.png" /></p>
<p>Então eu <strong>perdia o que eu realmente queria saber</strong>, como interações importantes do meu time ou PRs de projetos pessoais e <strong>via demais sobre o que eu não queria saber</strong>, tipo conversas de alguma issue aleatória de algum projeto que eu nem lembrava mais o que era.</p>
<p>O papel aqui é de ser similar a uma <em>Marie Kondo</em> em nossas notificações. Bora lá?</p>
<h2 id="heading-inscricoes">Inscrições</h2>
<p>Toda vez que você conversa em alguma <em>issue</em>, <em>pull request</em> ou alguem @menciona o seu username você está participando de uma <strong><em>conversa</em></strong> e portanto fica automaticamente fica inscrito nela como participante.
E por <em>default</em> recebemos notificações toda vez que estamos <strong>participando</strong> de algo.</p>
<p>Então você pode até hoje receber notificações de issues de muito tempo atrás e pra se livrar dela precisa não se esquecer de clicar para dar unsubscribe na issue em si assim que você vê-la.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611190990794/KREoPhUiz.png" alt="Screen Shot 2021-01-20 at 22.02.57.png" /></p>
<p>Mas para ter uma visão geral de tudo que você está inscrito basta entrar no <a target="_blank" href="https://github.com/notifications/subscriptions">Settings &gt; Subscriptions</a> e selecionar as issues que você quer dar unsubscribe 🔕.</p>
<p>Nessa listagem dá pra filtrar por mais antigos, ou por repositório também.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611191340615/0zyWxKOSi.png" alt="Screen Shot 2021-01-20 at 22.06.48.png" /></p>
<p>Pessoalmente essa é a parte mais chata de tudo. Eu por exemplo, deixei acumular muuuita coisa e o "selecionar tudo" pegava apenas 25 das inscrições, então tive que ir de 25 em 25.</p>
<p>Mas posso garantir que ver essa lista limpa valeu a pena pois agora posso organizar o que estou<strong> participando de verdade </strong>ou não!</p>
<p>Ah! Lembrando que você também recebe notificações de <em>gists</em> caso você seja um autor ou alguém te mencione. Mas claro, você também pode dar <em>subscribe</em> ou <em>unsubscribe</em> no botão bem do todo de qualquer gists.</p>
<h3 id="heading-assistindo">Assistindo</h3>
<p>Bem ao lado existe a pagina de <a target="_blank" href="https://github.com/watching">Watching</a> 📺. Esta pagina mostra todos os repositórios do Github que você assiste.</p>
<p>Quando você assiste um repositório tudo que interagirem você vai ser notificado, desde comentários, issues, mudanças de estado de issues, PRs etc e você vai notar que nessa lista deve incluir repositórios que você é dono ou chegou a dar fork.</p>
<p>Então por exemplo, ao mesmo tempo que eu eu assistia repositórios que eu interagi anos atrás , os quais eu sequer me importava ativamente com as atividades atuais e principalmente <strong>TODAS</strong> as interações que estavam acontecendo nele, eu não assistia repositórios os quais eu era realmente responsável em organizações e que muitas vezes tinham <em>pull requests</em> que eram abandonados 🕸🦇.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611191695119/QZ9tsQZ9q.png" alt="Screen Shot 2021-01-20 at 17.30.22.png" /></p>
<p>No botão de <em>watch</em> podemos escolher entre receber notificações normais de <strong>participação</strong>(ex: marcações), efetivamente<strong> assistir tudo</strong>,  <strong>ignorar completamente</strong>, como também pode customizar <strong>o que</strong> exatamente importa ou não no <em>custom</em>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611191759068/94cKfB0_e.png" alt="Screen Shot 2021-01-20 at 17.12.52.png" /></p>
<p>Então eu posso selecionar o que exatamente quero ser notificada, isso supre a necessidade de você só quer receber notificações de coisas importantes como PRs e issues.</p>
<p>Então é bom repensar o que importa e o que não importa e que tipo de notificações fazem sentido. <strong>Se você passa o olho e ignora talvez você deveria considerar para de assistir.</strong> <em>Does this spark joy??✨</em></p>
<p>Se não, <em>por que você precisaria estar inscrito em conversas especificas desse repositório?</em></p>
<p>É importante também não se deixar cair pelo <strong>FOMO</strong>(<em>Fear of missing out</em>), que é a ideia de você ter medo de estar "perdendo alguma coisa" e achar que precisa ter controle sobre tudo! 📵</p>
<p>Algumas perguntas boas são:</p>
<ul>
<li>Se você não colabora nesse projeto há anos será que um dia você vai mesmo voltar a ser ativo por lá?</li>
<li>Será que você pode aceitar que não faz sentido cuidar do seu projeto pessoal antigo?</li>
<li>Seu projeto incompleto precisa mesmo te assombrar até hoje?</li>
</ul>
<p>Caso você seja dono de algum projeto open source você também pode empaticamente ver se alguma <em>issue</em>, <em>commit</em> ou<em> pull request</em>  é irrelevante e dar "Lock" na conversa. Isso evita futuras notificações não só pra você mas pra todas as pessoas.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611193717762/reaMNSjJj.png" alt="Screen Shot 2021-01-20 at 22.48.10.png" /></p>
<p>Você pode encontrar o cadeadinho no canto inferior direito do que você quer bloquear 🔓.</p>
<h3 id="heading-times">Times</h3>
<p>Outra fonte de notificações desnecessárias são <strong>times</strong> 👯‍♀️. Caso seu time seja marcado em alguma discussão você recebera notificações para todas as respostas.
Além disso sendo code owner de algum projeto ou parte do código você fica como <strong>participando</strong> de tudo envolvido.</p>
<p>Em alguns casos isso é razoável mas em times grandes ou que tem muitas marcações de reviews, discussões etc vale a pena dar <strong>unfollow no time inteiro</strong> e manter o watch apenas em repositórios ou conversas que fazem sentido acompanhar.</p>
<p>Para ver os times que você é membro entre na organização do Github que você participa, clique na aba "Teams" dentro dos "Membros" da organização.
Seria esse link: <code>https://github.com/orgs/&lt;nome da organizacao&gt;/teams</code> e dentro do time aperte no botão de dar <em>unwatch</em>.</p>
<p>Talvez o seu grupo da faculdade, ou organização de que você não é ativo mais não são relevantes pro desenvolvedor que você é hoje!</p>
<p>Não hesite em <em>agradecer mentalmente pela oportunidade</em> 🙏 e sair dele.</p>
<h4 id="heading-inbox">Inbox</h4>
<p>Agora que já temos uma ideia sensata de como lidar com suas notificações falta saber lidar com elas.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611193811225/bhdj4RFLw.png" alt="Screen Shot 2021-01-20 at 22.49.38.png" /></p>
<p>Essa é a tela de notificações, você pode acessa-la pelo sininho no lado superior direito do seu github. Nela temos um inbox similar a seu email com todas as notificações.</p>
<p>Ainda bem que clicando em selecionar tudo você pode<strong> de fato</strong> selecionar todas as notificações do inbox.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611193908332/5eJmJkISO.png" alt="Screen Shot 2021-01-20 at 17.29.24.png" /></p>
<p>Doi um pouco o coração mas recomendo simplesmente deletar tudo e aceitar uma nova vida de notificações ao seu <strong>Github</strong> 🌈 <em>yay</em>.</p>
<h3 id="heading-triagem-e-filtros">Triagem e filtros</h3>
<p>Ao entrar no inbox não se esqueça de clicar nesse botão</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611199631757/jW380S6io.png" alt="Screen Shot 2021-01-20 at 17.18.02.png" /></p>
<p>Ele agrupa tudo do inbox por repositórios e isso deixa tudo muito mais claro.</p>
<p>O procedimento de triagem padrão é:</p>
<ul>
<li>Você vê a notificação no seu inbox</li>
<li>Caso você tenha visto você marca como <strong>DONE</strong>, o que tira ela do inbox.</li>
<li>Caso você saiba que essa notificação tem alguma relevancia e quer salvar para ver depois existe a ação de <strong>SAVE</strong>.</li>
<li>Caso não faça sentido a notificação pra você pode ver <strong>A RAZÃO</strong> e em seguida dar unsubscribe naquilo que não faz sentido pra você.</li>
</ul>
<p>Filtrando pela razão você pode facilmente saber sobre <strong>o que foi essa notificação</strong>, se foi marcação, mudança de status etc. Sabendo a razão para estar recebendo pode ser bom para saber o que vc precisa dar <em>unwatch</em>  ou não.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1611197244391/2fioFK4D-.png" alt="Screen Shot 2021-01-20 at 23.46.49.png" /></p>
<p>Na pagina de notificações temos alguns filtros automáticos, que são:</p>
<ul>
<li>🎯 <strong>Assigned</strong>: Notificações de PRs que você fez ou issues que você é responsável.</li>
<li>🗣 <strong>Participating</strong>: Notificações daquilo que você já comentou, foi marcado ou faz parte.</li>
<li>🖐 <strong>Mentioned</strong>: Notificações de pessoas especificamente te marcando.</li>
<li>🙌 <strong>Team Mentioned</strong>: Notificações de pessoas especificamente marcando o time marcando.</li>
<li>👀 <strong>Review requested</strong>: Tudo que precisaria do seu review seja pessoal ou do seu time.</li>
</ul>
<p>Eu também criei alguns filtros personalizados por exemplo:</p>
<p>Um para minha organização</p>
<blockquote>
<p>org:
Um para o repositório especifico
repo:/
Para menções me um repositório especifico
repo:/ reason:mention</p>
</blockquote>
<p>Vi que futuramente vai sair o filtro por <strong>type</strong> e o <strong>state</strong>
Sendo type o tipo como PR ou issue e state se está fechado, mergeado ou aberto.</p>
<p>Então por exemplo, para filtrar todos os PRs abertos de repositórios</p>
<blockquote>
<p>type:pr state:open repo:anabastos.</p>
</blockquote>
<p>Estou ansiosa para essa feature! 💕</p>
<h4 id="heading-configuracao">Configuração</h4>
<p>Por default, sempre que você tiver acesso a um novo repositório você automaticamente vai assistir esse repositório, e sempre que você entrar em um time novo você vai automaticamente ser inscrito todas as atualizações relativas ao time.</p>
<p>Mas dentro dos seus <a target="_blank" href="https://github.com/settings/notifications">Settings -&gt; Notifications</a> você tem a opção de desmarcar essa configuração de assistir automaticamente.</p>
<p><img src="https://docs.github.com/assets/images/help/notifications-v2/automatic-watching-options.png" alt="https://docs.github.com/assets/images/help/notifications-v2/automatic-watching-options.png" /></p>
<p><strong>Desmarcar essas opções é altamente recomendado</strong> porque você passa ter muito mais controle sobre o que quer ver ou não.</p>
<p>Nesta página de configurações você também pode configurar os seus emails, eu no caso não gosto de receber emails com esse tipo de notificação mas vi que existem pessoas que gostam de separar as notificações que recebem no Github e no Email, e na verdade até preferem via email porque ele tem a informação no próprio header, portanto pelo próprio Gmail por exemplo, você pode configurar as filtragens das notificações similar a <a target="_blank" href="[https://gist.github.com/ldez/bd6e6401ad0855e6c0de6da19a8c50b5](https://gist.github.com/ldez/bd6e6401ad0855e6c0de6da19a8c50b5)">este Gist</a> que eu achei.</p>
<p>Você pode ver mais sobre isso também na própria <a target="_blank" href="[https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications)">documentação do Github</a>.</p>
<p>Espero que tenha sido útil pra você esse post e que ajude na sua produtividade no geral no Github ✨🐙</p>
]]></content:encoded></item><item><title><![CDATA[Cartechmância — Tecnologias Mobile]]></title><description><![CDATA[Decidi ler o tarot das tecnologias mobile OLHA NO QUE DEU
Olá programadores místicos. Decidi ler o tarot das principais tecnologias mobile espero que vocês gostem.
IOS / Android Nativos
O Mago
Seu robe é branco simboliza a pureza, o nativo, e sua cap...]]></description><link>https://blog.anabastos.me/cartechmancia-tecnologias-mobile</link><guid isPermaLink="true">https://blog.anabastos.me/cartechmancia-tecnologias-mobile</guid><category><![CDATA[Mobile Development]]></category><category><![CDATA[Flutter]]></category><category><![CDATA[React Native]]></category><category><![CDATA[Ionic Framework]]></category><dc:creator><![CDATA[Ana Luiza Portello Bastos]]></dc:creator><pubDate>Wed, 20 Jan 2021 23:52:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1611187019982/AQLkJ30uo.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Decidi ler o tarot das tecnologias mobile <strong>OLHA NO QUE DEU</strong></p>
<p>Olá programadores místicos. Decidi ler o tarot das principais tecnologias mobile espero que vocês gostem.</p>
<h1 id="heading-ios-android-nativos"><strong>IOS / Android Nativos</strong></h1>
<h1 id="heading-o-mago"><strong>O Mago</strong></h1>
<p>Seu robe é branco simboliza a pureza, <strong><em>o nativo</em></strong>, e sua capa é vermelha simbolizada a sabedoria sobre tudo.</p>
<p>Um mão para cima direcionando para o universo, <em>o software,</em> e outra para baixo apontando para <em>o hardware</em>.</p>
<p>Isso nos mostra a conexão entre os dois que nada mais é do que a interface mais direta com o celular e seus recursos. Significando uma conexão mais fácil com cada um dos tipos de smartphones de <em>apple</em> a <em>android</em>. O mago tem controle sobre tudo que está acontecendo e isso em desenvolvimento nativo nos trás <strong>controle</strong>.</p>
<p>Na mesa do mago vemos <strong>RECURSOS</strong>. Todo o conhecimento de tecnologia adquirido com o passar dos anos está ao dispor do mago e seus recursos são o suficiente para criar e manifestar aplicações. Basicamente tudo necessário na ponta de seus dedos.</p>
<p><strong>O desenvolvedor nativo não é motivado pelo ego ou pelo hype mas sim com a conexão espiritual entre seu objetivo e suas intenções</strong>. Seu comprometimento é essencial e descarta qualquer distração para o que ele quer alcançar.Tenha certeza de se manter nos trilhos e se alinhar com o seu poder maior.</p>
<h1 id="heading-ionic-cordova"><strong>Ionic / Cordova</strong></h1>
<h1 id="heading-o-louco"><strong>O louco</strong></h1>
<p>Na gravura do louco vemos uma pessoa na beirada da montanha, distraída olhando para o céu está pronta para pular do precipício do desconhecido: <em>As aplicações híbridas.</em></p>
<p>Em suas costas, uma sacolinha modesta, um pouco conhecimento de JS e DOM aqui e ali. A rosa branca em sua mão esquerda representa sua pureza e inocência de achar que criar uma <em>webview</em> seria uma boa ideia.</p>
<p>Em seu pé, surpreendentemente temos um cachorro leal o protegendo que é a sua comunidade o seguindo sem muita reflexão sobre suas escolhas.</p>
<p>As montanhas atrás do louco simbolizam os desafios, que estão sempre presentes, as quais o Louco não liga. Ele não tem medo ou ansiedade sobre performance ou sobre como as coisas serão padronizadas de celular para celular. Ele fez um curso de Angular na net, o cliente falou “preciso de um app” e ele só encapsulou o que ele sabia e isso foi o suficiente pois ele entregou no prazo.<strong>Para o louco a hora é agora.</strong></p>
<p>O louco nos convida a aceitar a vida como ela é. Até <em>spotify</em> e <em>atom</em> são grandes <em>webviews</em> e talvez devemos abraçar mais a produtividade e a liberdade de um <em>cordova</em>.</p>
<h1 id="heading-flutter"><strong>Flutter</strong></h1>
<h1 id="heading-a-temperanca"><strong>A temperança</strong></h1>
<p>Na carta temos um anjo com um pé nas pedras e outro na agua, mostrando a necessidade de estar fluindo ao mesmo tempo de estar sobre bases sólidas. <strong>Temperança simboliza um meio de alcançar todas as perspectivas de forma não opinionada ou controversa.</strong></p>
<p>A temperaça não é sobre algo extremamente novo mas sim algo que já temos experiência e estamos familiares. A ideia do <em>Flutter</em> não é algo extremamente revolucionário, mas sim similar com algo que <em>Xamarim</em> por exemplo já fazia. <em>Dart</em> também não é uma linguagem nova, ela é uma filha perdida da <em>Google</em> que já havia sido abandonada antes mas é muito similar ao <em>Javascript,</em> que já conhecemos amplamente, mas com muito mais estabilidade .</p>
<p>O anjo derrama agua entre os copos simbolizando <strong>misturas de técnicas e estilos</strong>. Essa harmonia de experiências é o crescimento e estabilidade que o <em>Flutter</em> nos trás e mostra que não é sobre correr ou re-inventar a moda mas sim garantir o melhor resultado de acordo com suas experiências.</p>
<p>No fundo da carta temos um caminho para uma montanha com o topo brilhante mostrando que quem o usa está no caminho superior e sendo <strong>honesto com sua proposta.</strong></p>
<h1 id="heading-react-native"><strong>React Native</strong></h1>
<h1 id="heading-o-carro"><strong>O carro</strong></h1>
<p>O carro mostra um guerreiro dentro de uma carruagem vestindo uma armadura representando o esforço e o refinamento da biblioteca para estar no mercado como uma<strong>opção fortissima para o desenvolvimento mobile.</strong></p>
<p>A folha de louro mostra o sinal de vitória, sucesso e evolução espiritual nos mostrando tudo que tivemos de passar para conseguir desenvolver aplicações cross-native em Javascript e impõe responsabilidade e poder mostrando quem está mandando no mercado.</p>
<p>A estrela de seis pontas em cima da carta é a conexão entre dois planos, a comunidade e a ferramenta, por isso a o React sempre lança coisas que a comunidade já precisava e sentia falta.</p>
<p>O carroceiro representa o <em>Facebook</em> que não tem redeas e fica sempre de pé, tomando ações e indo em frente introduzindo novas funcionalidades. É uma carta ativa e rápida, assim como a comunidade Javascript, <strong>vai mudar sua abordagem quando necessário e não tem medo de deprecar todas as bibliotecas comuns!</strong></p>
<p>Na frente da carta vemos duas esfinges, temos a as forças opostas: o branco e o preto, o negativo e o positivo, <strong>o componente em classe e o componente funcional stateless.*</strong>O conflito e a dualidade faz com que a carroça sempre vá pra frente agradando quem for.*</p>
<p>Outras ferramentas podem tentar distrair ou tirar o React Native de foco mas a carroça é um convite para quebrar os limites do Javascript e da Web.React Native vai se manter bem no mercado por um bom tempo.</p>
<p>Se você quer ser ousado, expressar o que você quer sem medo de se prender conte com o React Native pois nada é mais dinâmico e aberto para novos estilos e ferramentas como o ecossistema Javascript.É um caminho <strong>sofrido*</strong>(uma curva de aprendizagem tortuosa e cheia de erros de terminal misteriosos)<em> porém <strong>cheio de gloria</strong></em>(bons salários por falta de profissionais)*</p>
<h1 id="heading-reasonml"><strong>ReasonML?</strong></h1>
<p>Tirei essa carta como uma aposta pessoal para um futuro.</p>
<p>Temos um lindo ecossistema similar a <em>Javascript</em>, em que além de contarmos com um sistema de tipos ótimo conseguimos compilar aplicações nativas para qualquer coisa de forma extremamente otimizada. Quais as chances de no futuro termos uma opção popular <em>OCaml</em> like para desenvolvimento mobile?</p>
<h1 id="heading-o-enforcado"><strong>O Enforcado</strong></h1>
<p>O enforcado mostra um homem suspenso em uma cruz de madeira de cabeça pra baixo vendo o mundo de uma perspectiva completamente diferente. Sua expressão facial é tranquila e serena mostrando a falta de preocupação com erros em <em>runtime</em>, a auréola em sua cabeça mostra sua iluminação. E qual a razão de tamanha consciência? <strong><em>um compilador muito bom.</em></strong></p>
<p>A carta representa o sacrifício e a rendição ao bem maior.Seu pé direito está amarado a origem, o <em>OCaml e a familia ML</em> que nós provê um refinamento de 50 anos, e o seu pé esquerdo solto mostrando sua ligação o Javascript, um <em>interop</em> e uma sintaxe familiar.Sua veste o azul mostra <em>sabedoria,</em> os tipos<em>,</em> e o vermelho de sua calça mostra a <em>paixão</em>, a programação funcional.</p>
<p>O enforcado convida a receber a realidade como ela é mesmo quando ela é completamente diferente do que você esperava. <strong>É o universo te convidando para olhar para computação de forma diferente e te preparando para o melhor da vida.</strong></p>
<p>— — — — — — — — — — — — — —</p>
<h1 id="heading-sim-eu-realmente-tirei-essas-cartas"><strong>Sim, eu realmente tirei essas cartas.</strong></h1>
<p>Essa semana vou tirar sobre Frameworks Javascript. Me aguardem.</p>
<p>Espero que você tenha gostado do artigo 💙💚❤️🧡💛</p>
<p><strong>Quem gostou bate palminha pra que essa mensagem alcance outros amiguinhos.</strong></p>
<p><strong>👏 👏 👏 👏 👏 👏 👏 👏 👏*</strong>OBS: As diferenças entre os desenhos e a interpretação são pq as imagens são do tarot de Marselha e o meu é outro.*</p>
]]></content:encoded></item><item><title><![CDATA[Flat/FlatMap do Javascript na Prática]]></title><description><![CDATA[Aprendendo a utilizar as novas operações de Array do Javascript
A proposta
Foram confirmadas recentemente as novas propostas de funcionalidades que chegaram no estágio 4 do ECMAScript, significando que estarão na proxima especificação oficial e terão...]]></description><link>https://blog.anabastos.me/flatflatmap-do-javascript-na-pratica</link><guid isPermaLink="true">https://blog.anabastos.me/flatflatmap-do-javascript-na-pratica</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[Ana Luiza Portello Bastos]]></dc:creator><pubDate>Sun, 20 Dec 2020 20:00:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1608494425631/iLlNYQdfZ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Aprendendo a utilizar as novas operações de Array do Javascript</p>
<h1 id="heading-a-proposta"><strong>A proposta</strong></h1>
<p>Foram confirmadas recentemente as novas propostas de funcionalidades que chegaram no <a target="_blank" href="https://tc39.github.io/process-document/">estágio 4</a> do <a target="_blank" href="https://pt.wikipedia.org/wiki/ECMAScript">ECMAScript</a>, significando que estarão na proxima especificação oficial e terão sua implementação na linguagem!!</p>
<p>Dentre elas temos dois novos bebês ❤ chamados <code>Array.prototype.flat()</code> e o <code>Array.prototype.flatMap()</code>, baseados na <a target="_blank" href="https://github.com/tc39/proposal-flatMap">proposta do Michael Ficarra, Brian Terlson, Mathias Bynens</a>. Mas qual a importancia deles e como podemos utiliza-los?</p>
<p>O <strong><em>flatMap*</em></strong>(Muitas vezes chamado de concatMap ou &gt;&gt;= em outras linguagens)<em> é um pattern comum que vem da programação funcional de linguagens como </em>Scala<em> ou </em>Haskell.<em> Esta operação de </em>array* pode nos ajudar solucionar problemas em que temos de iterar por exemplo, arrays com itens complexos. Você pode já ter ouvido falar de <a target="_blank" href="https://www.learnrxjs.io/operators/transformation/mergemap.html">implementações similares de Flatmap por exemplo no RxJS para lidar com Observables</a>.</p>
<p>Mas diferente de outras linguagens, que utilizam o <strong><em>flatMap</em></strong> como uma operação para manipular <strong><em>objetos, strings</em></strong>, tendo usos até mesmo como meio de lidar com valores <strong><em>opcionais</em></strong> e <strong><em>monadas.</em></strong> A sua implementação no Javascript se limita a <strong>apenas operações de <em>arrays.</em></strong></p>
<p>Estamos familiares com funções como o ***<a target="_blank" href="http://equinocios.com/swift/2017/03/13/Introducao-e-casos-de-uso-Map-Filter-e-Reduce/">map***, <strong><em>filter</em></strong> e <strong><em>reduce</em></strong></a> que são responsáveis por transformar os elementos do arrays em novos valores a partir de uma função.</p>
<pre><code class="lang-plaintext">.map// [2, 3, 4]filter// [1 , 3]reduce// 6
</code></pre>
<p>Similarmente, o <strong><em>flatMap</em></strong> recebe uma função como argumento e funde os conceitos de <strong><em>flat</em></strong> com o já conhecido <strong><em>map*</em></strong>.*</p>
<p>Mas o que é o flat?</p>
<h1 id="heading-arrayprototypeflat"><strong>Array.prototype.flat()</strong></h1>
<p>O <code>Array.prototype.flat()</code>, também conhecido como <em>flatten</em>, tem o intuito de deixar nosso array plano recursivamente em uma profundidade especificada como argumento, ou seja, é uma operação que concatena os elementos de um <em>array.</em></p>
<p>Por padrão a função de <em>flat</em> planifica em um nível(<code>.flat(1)</code>) como no exemplo:</p>
<pre><code class="lang-plaintext">.flat// [ 1, 2, 3, 4].flat// [ 1, 2, 3, 4, [5, 6]]
</code></pre>
<p>Passando o número 2 como argumento a função fica plana em 2 níveis.</p>
<pre><code class="lang-plaintext">.flat// [ 1, 2, 3, 4, 5, 6 ]
</code></pre>
<h1 id="heading-alguns-usos-praticos-do-flat"><strong>Alguns usos praticos do Flat</strong></h1>
<p><strong>Concatenando arrays</strong></p>
<p>Supondo dois arrays contendo alguns números que devem ser concatenados em apenas um array.</p>
<pre><code class="lang-plaintext">constconst
</code></pre>
<p>Uma forma de fazer isso seria mutar algum destes arrays e utilizar a operação <strong><em>push</em></strong> para inserir os valores do outro array dentro do outro.</p>
<pre><code class="lang-plaintext">.push// [1, 2, 3, 4, 5, 6]
</code></pre>
<p>Outro método comum caso eu queria criar um novo array seria utilizar o <a target="_blank" href="https://medium.com/magnetis-backstage/p%C3%ADlulas-de-javascript-operador-spread-e-par%C3%A2metro-rest-afd1f0266036"><em>spread</em></a> dos arrays dentro de um novo array concatenando seus elementos.</p>
<pre><code class="lang-plaintext">const// [1, 2, 3, 4, 5, 6]
</code></pre>
<p>A operação de <strong><em>flat</em></strong> nos introduz uma maneira interessante sem a necessidade de <em>spreads</em> para concatenar o elementos deste array.</p>
<pre><code class="lang-plaintext">flat
</code></pre>
<p><strong>Condicionalmente inserindo valores em um array.</strong></p>
<p>Supondo que caso uma condição seja verdadeira, devo inserir um valor dentro de um array.</p>
<p>Uma forma mais sucinta seria ao invés de um “if”, considerar essa condicional na propria criação array, colocando um ternário no proprio array. Caso a condição é verdadeira, insere o valor ‘a’, caso contrário insere <em>null</em>.</p>
<pre><code class="lang-plaintext">constconst?:// ['b', null]
</code></pre>
<p>Em condições positivas teremos o elemento esperado ‘a’, mas caso contrário teremos um array sujo com valores <em>“null”</em> e para isso seria necessário de alguma forma filtrar esses valores.</p>
<pre><code class="lang-plaintext">filter// ['b']
</code></pre>
<p>Com o <em>flat</em> podemos fazer de forma simples a inserção de valores caso a condição é verdadeira com uma condicional (<code>cond **?** ['a'] **:** []</code>). Pois já que o proprio flat concatena arrays, a concatenação de um array vazio caso uma condição falsa não geraria a insersão de valores desnecessários.</p>
<pre><code class="lang-plaintext">constconst?:.flat// ['b']
</code></pre>
<p><strong>Criando uma copia de um array</strong></p>
<p>Quando queremos criar uma copia de um <em>arr</em> mudando sua referencia.</p>
<pre><code class="lang-plaintext">constconstflat// [1,2,3,[4]]// [3,2,3,[4]]
</code></pre>
<p>Note que isso vai apenas retornar uma “<em>shallow copy</em>”. Ou seja, objetos dentro do array não serão clonados.</p>
<h1 id="heading-arrayprototypeflatmap"><strong>Array.prototype.flatMap()</strong></h1>
<p>O <strong><em>flatMap</em></strong> é basicamente um <strong><em>map</em></strong> com <strong><em>flat</em></strong>. Como assim?</p>
<p>Com o <strong><em>map</em></strong>, cada elemento do array é iterado e apartir de uma função<code>f</code>retorna um novo array com cada um desses valores transformados. A função <code>f</code>que recebe um elemento <em>input</em> e torna um elemento <em>output</em>.</p>
<p>Com o <strong><em>flatMap</em></strong>, cada elemento é iterado e apartir de uma função <code>f</code> retorna um array de valores. A função <code>f</code>que recebe um elemento <em>input</em> e e cada elemento pode ser transformado em nenhum ou mais elementos de <em>output</em>.</p>
<p><img src="https://miro.medium.com/max/60/1*aVV-YQA8RRx0R6ZV32MGEA.jpeg?q=20" alt="https://miro.medium.com/max/60/1*aVV-YQA8RRx0R6ZV32MGEA.jpeg?q=20" /></p>
<p><img src="https://miro.medium.com/max/2560/1*aVV-YQA8RRx0R6ZV32MGEA.jpeg" alt="https://miro.medium.com/max/2560/1*aVV-YQA8RRx0R6ZV32MGEA.jpeg" /></p>
<p>Relação entre Map(One to one) e FlatMap(One to many)</p>
<p>Ambos <strong><em>flatMap</em></strong> e <strong><em>map</em></strong> recebem uma função <code>f</code> como argumento que gera um novo array de retorno com base nos items do array de origem.</p>
<p>Sequencialmente o <strong><em>flatMap</em></strong> seria similar a aplicação de uma função dentro de um <strong><em>map</em></strong> seguido de uma operação de <strong><em>flat</em></strong> planificando o <em>Array</em>.</p>
<pre><code class="lang-plaintext">map//[[1, 100], [2, 200], [3, 300]].flat() // [1, 100, 2, 200, 3, 300]flatMap// [1, 100, 2, 200, 3, 300]
</code></pre>
<p>Similarmente, usando o <strong><em>flatMap</em></strong> com uma função identidade(<code>x =&gt; x</code>), em que inutilizamos o seu <strong><em>map</em></strong>, temos exatamente o que seria apenas um <strong><em>flat</em></strong>.As seguintes operações são equivalentes:</p>
<pre><code class="lang-plaintext">flatMapmapflatflat
</code></pre>
<h1 id="heading-alguns-usos-praticos-do-flatmap"><strong>Alguns usos praticos do FlatMap</strong></h1>
<p><strong>Filtrar e transformar arraysExemplo 1</strong></p>
<p>Podemos utilizar a operação de flapMap() como meio de filtrar elementos em arrays e transforma-los.</p>
<p>Supondo uma array de numeros de 1 a 10.</p>
<pre><code class="lang-plaintext">const
</code></pre>
<p>Queremos transformar este array em apenas numeros <strong>antecessores</strong> de <strong>numeros primos</strong>. Supondo que eu tenho uma função <em>isPrime</em> que me retorna verdadeiro ou falso caso o numéro é um primo. Podemos primeiramente utilizar a função <em>filter</em> para filtrar os valores em apenas primos*.*</p>
<pre><code class="lang-plaintext">filterisPrime// [2, 3, 5, 7]
</code></pre>
<p>Porém para listar os antecessores do array teriamos de <strong>novamente</strong> iterar pelos itens para retornar um novo array com cada valor subtraido por 1.</p>
<pre><code class="lang-plaintext">filterisPrimemap// [1, 2, 4, 6]
</code></pre>
<p>Com o <strong><em>flatMap</em></strong> podemos fazer ambas as operações em apenas uma iteração de array em que com uma operação ternária retornamos ou um array com o valor subtraido por 1 ou uma array vazio.</p>
<pre><code class="lang-plaintext">flatMapisPrime?:// [1, 2, 4, 6]
</code></pre>
<p>Sendo assim: é um <strong><em>map</em></strong>, que iteraria os 10 elementos do <em>array</em> e geraria 10 <em>arrays</em>, seguido de um <strong><em>flat</em></strong> planificando em apenas um <em>array</em>:</p>
<pre><code class="lang-plaintext">map// [[],[1],[2],[],[4],[],[6]..]flat// [1, 2, 4, 6]
</code></pre>
<p><strong>Exemplo 2</strong></p>
<p>Tenho um array de ids de objetos e uma propriedade booleana indicando se este item deve ou não ser listado, se sim devo dar fetch nesta propriedade.</p>
<pre><code class="lang-plaintext">constidtoListidtoList
</code></pre>
<p>Sem o <strong><em>flatMap</em></strong> uma solução viavel seria utilizar o <strong><em>filter</em></strong> para filtrar caso a propriedade <em>toList</em> é verdadeira e em seguida seria necessário utilizar um <strong><em>map</em></strong> para efetivamente dar fetch nesses ids.</p>
<pre><code class="lang-plaintext">filtermap// [Promise]
</code></pre>
<p>Com apenas um flatMap podemos resolver este problema criando uma função em que caso o <em>toList</em> é verdadeiro ele retorna um array com o fetch do id, caso contrário retorna um array vazio que será concatenado.</p>
<pre><code class="lang-plaintext">Promise.allflatMap// [...]
</code></pre>
<p><strong>Exemplo 3</strong></p>
<p>Podemos usar para extrairmos apenas um tipo de dado de um objeto em tratativas. Por exemplo, em um array de objetos cuja tratativa de erros de um <strong><em>try / catch</em></strong> retorna apenas os valores dos resultados ou apenas os erros.</p>
<pre><code class="lang-plaintext">tryreturncatchreturn
</code></pre>
<p><strong><em>flatMap</em></strong> pode ser nosso aliado para podermos extrair apenas os erros ou apenas os valores especificos destes resultados por meio de uma operação ternária:</p>
<pre><code class="lang-plaintext">constflatMapconstflatMap
</code></pre>
<p><strong>Pegando elementos de um array de objetos com arrays aninhados.</strong></p>
<p>Supondo que tenho um array de objetos de cestas de frutas em que dentro do objetos listamos em “itens” as frutas dentro da cesta.</p>
<pre><code class="lang-plaintext">constiditensMaçaBananaiditensBananaAbacaxi
</code></pre>
<p>Se quero listar todas as frutas dentro de cestas no map seria necessário iterar pelo array e pegar a propriedade “itens” de cada objeto.</p>
<pre><code class="lang-plaintext">map// [Array(2), Array(2)]
</code></pre>
<p>Apenas com o map teriamos <em>arrays</em> de <em>arrays</em>.</p>
<pre><code class="lang-plaintext">flatMap// [“Maça”, “Banana”, “Banana”, “Abacaxi”]
</code></pre>
<p>Com o <strong><em>flatMap</em></strong> já temos a concatenação dos elementos do array e conseguimos obter todos os elementos listados dentro de objetos.</p>
<p><strong>Indexando em lista</strong></p>
<p>Supondo uma lista de compras, para listá-las entre vírgulas em um componente “GroceryList” podemos utilizar o <strong><em>flatMap.</em></strong> A função cujo metodo recebe pode ter um segundo argumento com o index do array assim como o <strong><em>map</em></strong> ou <strong><em>filter</em></strong>. Por exemplo:</p>
<pre><code class="lang-plaintext">.map// ['0Foo', '1Bar']
</code></pre>
<p>Quando retornamos um array desta função, os seus elementos são concatenados e podemos adicionar elementos condicionais (como por exemplo, a vírgula após o primeiro elemento da lista).</p>
<pre><code class="lang-plaintext">classextendsrenderconstthisreturnflatMapfoodindexindexindexfoodfood
</code></pre>
<h1 id="heading-suporte-de-navegadores"><strong>Suporte de Navegadores</strong></h1>
<p>O <strong><em>flat</em></strong> e o <strong><em>flatMap</em></strong> já estão com suporte nos principais navegadores(<em>Chrome 69, Firefox 62, Opera 56, Safari 12, Android WebView 69</em>) e na versão <em>11.0.0</em> do <em>NodeJs ❤️🧡💛💚💙💜.</em></p>
<p>É possivel tambem importar proposals pelo <em>Babel 7</em>. Pelo <em>FlatMap</em> já estar em <em>stage 4</em> é <a target="_blank" href="https://babeljs.io/docs/en/v7-migration#remove-proposal-polyfills-in-babel-polyfill-https-githubcom-babel-babel-issues-8416">preciso importar especificamente a funcionalidade.</a></p>
<h1 id="heading-conclusao"><strong>Conclusão</strong></h1>
<p>Cada vez mais vemos mudanças para agradar todas as formas / paradigmas do Javascript. Desde 2015 vemos a linguagem suportando outros estilos de orientação a objetos, e agora vemos a adição de elementos comuns de linguagens funcionais como <strong><em>FlatMap</em></strong> e quem sabe futuramente o <a target="_blank" href="https://github.com/tc39/proposal-pipeline-operator"><strong><em>Pipeline Operator</em></strong></a>, <a target="_blank" href="https://github.com/tc39/proposal-pattern-matching"><strong><em>Pattern Matching</em></strong></a> e <a target="_blank" href="https://github.com/tc39/proposal-partial-application"><strong><em>Partial Application</em></strong></a> 🤞.</p>
<h1 id="heading-espero-que-voce-tenha-gostado-do-artigo"><strong>Espero que você tenha gostado do artigo ❤</strong></h1>
<p><strong>Quem gostou bate palminha pra que o artigo alcançe outros amiguinhos.👏 👏 👏 👏 👏 👏 👏 👏 👏</strong></p>
]]></content:encoded></item><item><title><![CDATA[O que tem de novo no ES2020(es11)]]></title><description><![CDATA[Vamos ver mais de perto as coisas incríveis que chegaram agora na nova especificação do ECMAScript! 🤩
Todo ano uma nova versão da especificação ECMAScript sai com as propostas de features, para isso o comitê da TC39 faz um exaustivo processorefinand...]]></description><link>https://blog.anabastos.me/o-que-tem-de-novo-no-es2020es11</link><guid isPermaLink="true">https://blog.anabastos.me/o-que-tem-de-novo-no-es2020es11</guid><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Ana Luiza Portello Bastos]]></dc:creator><pubDate>Sun, 26 Apr 2020 23:54:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1611186949562/iyKpaMX7G.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Vamos ver mais de perto as coisas incríveis que chegaram agora na nova especificação do <em>ECMAScript</em>! 🤩</p>
<p>Todo ano uma nova versão da especificação <em>ECMAScript</em> sai com as propostas de <em>features,</em> para isso o <a target="_blank" href="https://tc39.es/process-document/">comitê da TC39 faz um exaustivo processo</a>refinando as propostas até serem serem aceitas e passaram para seu estado final,o <a target="_blank" href="https://github.com/tc39/proposals/blob/master/finished-proposals.md">stage 4</a>, que define o que estará presente no proximo <em>draft</em>.Essas <em>features</em> serão consideradas <strong>estáveis</strong> assim que dois navegadores as implementarem.</p>
<p>Esse processo garante uma melhora constante no estado da arte do Javascript 👩‍🎨.</p>
<p>Todas as features para a especificação de 2020(<em>ES2020</em>) **estão finalizadas,**significando que estão prontas para serem <strong>implementadas em navegadores, engines e ferramentas!</strong></p>
<p>➡️ BigInt➡️ Classes Privadas➡️ Optional Chaining➡️ Nullish coalescing Operator➡️ String.prototype.matchAll➡️ globalThis➡️ for-in mechanics➡️ Promise.allSettled➡️ Dynamic Imports➡️Module Namespace Exports➡️ import.meta</p>
<h1 id="heading-as-propostas"><strong>As propostas 🖋</strong></h1>
<h1 id="heading-biginthttpsgithubcomtc39proposal-bigint"><a target="_blank" href="https://github.com/tc39/proposal-bigint"><strong>BigInt</strong></a> <strong>🧮</strong></h1>
<p>Quem está habituado a usar números em JS já sofreu muito em relação a limitação do seu tipo <strong>number,</strong> que não passa de um double de 64 bits, tendo assim uma limitação de até um certo número que podemos fazer operações de forma “segura”.</p>
<pre><code class="lang-plaintext">// Número máximo seguro no JS
Number.MAX_SAFE_INTEGER // 9007199254740991
</code></pre>
<p>Para isso é comum dependermos de bibliotecas externas para tentar lidar de forma mais segura com valores altos.</p>
<p><code>BigInt</code> é agora o <strong>sétimo tipo primitivo</strong> dentro da linguagem, servindo somente pra lidar somente com precisão de inteiros. Pois uma variável deste tipo pode representar 2⁵³ números.</p>
<p>Com a nova especificação podemos indicar o tipo <code>BigInt</code> somente colocando uma letra <code>n</code> no final do número, denotado para a engine Javascript(v8 ou qualquer outra) como o número ser tratado.</p>
<pre><code class="lang-plaintext">const numeroGrande = 100000000000000000000000000000n;
console.log(numeroGrande * 2n); // 200000000000000000000000000000n
</code></pre>
<p>Podemos fazer <em>casting</em> para esse novo tipo desta forma.</p>
<pre><code class="lang-plaintext">console.log(BigInt(Number.MAX_SAFE_INTEGER))
// 9007199254740991n
</code></pre>
<p>É importante lembrar que essa coersão de <code>Number</code> para <code>BigInt</code> pode causar perda de precisão então o ideal é já definir números como <code>BigInt</code>quando se tem a certeza que eles podem ser grandes.</p>
<p><code>BigInt</code> já foi implementado nos maiores navegadores como Chrome, Firefox, opera e a versão 10.4 do Node.js e está bem <strong>estável ✅</strong></p>
<p><strong>📖</strong><a target="_blank" href="https://tc39.es/ecma262/#sec-bigint-objects"><strong>Especificação</strong></a><strong>🗼</strong><a target="_blank" href="https://babeljs.io/docs/en/babel-plugin-syntax-bigint"><strong>Plugin Babel</strong></a></p>
<h1 id="heading-classes-privadashttpsgithubcomtc39proposal-private-methods"><a target="_blank" href="https://github.com/tc39/proposal-private-methods"><strong>Classes Privadas</strong></a> <strong>🔒</strong></h1>
<p><em>JS</em> sempre foi uma linguagem orientada a objetos mas por sua implementação com base em protótipo ao invés de classes, apesar de termos a sintaxe especial de <code>Class</code>desde de a <em>ES2015,</em> por conflitos de decisões de implementação não tínhamos como fazer métodos ou campos privados nativamente.</p>
<p>Quando usamos classes em Javascript temos como padrão nomear elementos privados com um <code>_</code>na frente como meio de diferenciação.</p>
<p>Com a nova especificação colocar o sinal de <code>#</code>na frente da variável ou função já vai definir que o <strong>não se deve ter acesso a ele em outros contextos além da própria classe</strong>.</p>
<p>Apesar de parecer contra intuitivo, essa decisão se deve exatamente ao fato de que muitas bibliotecas já aderiram o sublinhado <code>_</code> como meio de marcar campos privados, sendo um meio de evitar alterações já existentes.</p>
<p>Isso pode causar um estranhamento também pra quem vem do <em>Typescript</em>cuja sintaxe já amplamente conhecida para definir se algo é privado também é o <code>_</code> .</p>
<p>Dessa forma podemos escrever classes similares a essa:</p>
<pre><code class="lang-plaintext">class Counter {
  #x = 0;             // Define uma variável privada
  increment() {
    this.#x++;        // Incrementa a variável privada
  }
  decrement() {
    this.#x--;        // Decrementa a variável privada
  }
  getX(){
    return this.#x;
  }
}const c = new Counter();console.log(c.getX()); // 0 -&gt; Valor é exposto pelo metodo getX
</code></pre>
<p>Tentar pegar o valor da variável privada diretamente não é viável pois ela não pode ser acessada fora do contexto da classe.</p>
<pre><code class="lang-plaintext">c.#x =&gt; 🙅‍♀Uncaught SyntaxError: Private field '#x'
</code></pre>
<p>Os métodos modificam o campo x e o resultado final retornado por por <code>getX</code> é o valor -1.</p>
<pre><code class="lang-plaintext">c.increment(); 
c.decrement();
c.decrement();
console.log(c.getX()); // -1 -&gt; Valor é modificado e depois exposto
</code></pre>
<p>Supondo que no meu exemplo não quero que o contador chegue em valor abaixo de 0 e quero criar uma função auxiliar privada para fazer essa verificação.</p>
<pre><code class="lang-plaintext">class Counter {
  #x = 0;     
  increment() {
    this.#x++;       
  }
  #isPositive() {
    return this.#x &gt; 0
  }
  decrement() {
    if (this.#isPositive()) this.#x--;  
  // Chama o método privado para verificar se o valor x é positivo
  }
  getX(){
    return this.#x;
  }
}const c = new Counter();
</code></pre>
<p>Assim como a propriedade privada, não posso chamar o método novo fora do contexto da classe.</p>
<pre><code class="lang-plaintext">c.#isPositive() =&gt; 🙅‍♀Uncaught SyntaxError: Private method '#x'
</code></pre>
<p>Desta forma ao chamar a função decrement podemos ter a garantia que nosso valor não será negativo.</p>
<pre><code class="lang-plaintext">c.decrement();
console.log(c.getX()); // 0
</code></pre>
<p>Isso é de extrema importante pois até então tínhamos dificuldade de seguir os <strong>princípios de SOLID</strong> pois não tínhamos como suprir o <strong>Open/Closed</strong>principle.</p>
<p>Essa feature já está na ultima versão do <em>Chrome</em> e do <em>Node v12</em>.</p>
<p><strong>📖</strong><a target="_blank" href="https://tc39.es/proposal-private-methods/"><strong>Especificação</strong></a><strong>🗼</strong><a target="_blank" href="https://babeljs.io/docs/en/babel-plugin-proposal-private-methods"><strong>Plugin Babel</strong></a></p>
<h1 id="heading-optional-chaining-operatorhttpsgithubcomtc39proposal-optional-chaining"><a target="_blank" href="https://github.com/tc39/proposal-optional-chaining"><strong>Optional Chaining Operator</strong></a> <strong>❓</strong></h1>
<p>Quem nunca passou ou ouviu falar do famoso <em>“Cannot read property of undefined”</em>? Javascript pode ser <em>tricky</em> quando estamos lidando com valores <em>nulos</em> ou <em>undefined</em>.</p>
<p>Pelo dinamismo do Javascript precisamos muitas vezes fazer <strong>múltiplas verificações para conseguir pegar propriedades de qualquer objeto</strong>para tentar evitar receber um erro pois uma delas está nula.</p>
<p>Supondo um objeto com dados de um "usuário" que pode*(ou não)* conter informações do perfil de uma pessoa.</p>
<pre><code class="lang-plaintext">user // undefined
user.profile // Error : Cannot read property of undefined
user.profile.name // Error : Cannot read property of undefined
</code></pre>
<p>Quando tentamos pegar a propriedade de um objeto, o código espera que seja um objeto válido, jogando um erro caso o seu valor seja inesperado.</p>
<p>Quando não temos a garantia dos valores e temos de pegar por exemplo, uma propriedade <code>name</code> em segundo nível do objeto teríamos de fazer diversas verificações.</p>
<pre><code class="lang-plaintext">if (user != undefined &amp;&amp; user.profile != undefined) {
 user.profile.name 
}
</code></pre>
<p>Adicionando o novo operador interrogação antes do ponto nós conseguimos interagir com o caminho opcional. Caso ele exista, temos acesso ao resultado esperado.</p>
<pre><code class="lang-plaintext">const user = {profile: name: "Maria"}
user?.profile?.name // “Maria”
</code></pre>
<p>Caso algum valor comparado pelo operador não exista ele retorna apenas um <em>undefined</em> sem mais erros.</p>
<pre><code class="lang-plaintext">const user = {}user?.profile?.name // Undefined
</code></pre>
<p>Isso não se limita a objetos ou arrays mas também pode ser usado em funções a serem executadas.</p>
<pre><code class="lang-plaintext">user.profile.checarAlgo?.(...argumentos)
</code></pre>
<p>Essa sintaxe também pode ser usada para acesso dinâmico da propriedade</p>
<pre><code class="lang-plaintext">user.profile?.[nomeDaPropriedade]
</code></pre>
<p>Isso é especialmente interessante quando queremos um valor dentro de uma estrutura muito grande que precisamos sempre ficar checando se cada parte da estrutura existe ou não.</p>
<pre><code class="lang-plaintext">// Com operador
a?.b[3].c?.(x).d
// Sem operador
a == null ? undefined : a.b[3].c == null ? undefined : a.b[3].c(x).d
</code></pre>
<p>O operador de <strong>Optional Chaining</strong> permite lidar com a talvez existência de valores de forma limpa, consistente e sem que a gente se repita fazendo múltiplas verificações desnecessárias para o mesmo elemento. A sintaxe foi inspirada de linguagens como <em>C#</em> e <em>Swift</em> e também certamente do <em>Typescript</em>, que já tem essa funcionalidade nativa.</p>
<p>A funcionalidade já está implementada nos principais navegadores, engines e ferramentas!</p>
<p><strong>📖</strong><a target="_blank" href="https://tc39.es/proposal-private-methods/"><strong>Especificação</strong></a><strong>🗼</strong><a target="_blank" href="https://babeljs.io/docs/en/babel-plugin-proposal-private-methods"><strong>Plugin Babel</strong></a></p>
<h1 id="heading-nullish-coalescing-operatorhttpsgithubcomtc39proposal-nullish-coalescing"><a target="_blank" href="https://github.com/tc39/proposal-nullish-coalescing"><strong>Nullish Coalescing Operator</strong></a> <strong>⏸</strong></h1>
<p>É bem comum fazermos verificações para checar se um valor especifico é <strong>falsey</strong>(<em>null, undefined, etc)</em> para tratarmos da forma mais apropriada para não quebrarmos nosso código ou expormos acidentalmente esses valores para o usuário.</p>
<p>Quando queremos acessar propriedades de um objeto que não temos certeza de sua existência é comum usarmos um valor <em>default</em>. Tentamos algo similar a isso:</p>
<pre><code class="lang-plaintext">user.profile.name == undefined ? “Anonymous” : person.profile.name
user.profile.age == undefined ? 0 : person.profile.age
</code></pre>
<p>Também podemos tentar expressar a mesma coisa por meio do operador barra-barra ou OR =&gt; ||.</p>
<pre><code class="lang-plaintext">false || “Texto teste” // Texto teste
undefined || “Texto teste” // Texto teste
null ||"Texto teste" // Texto teste
NaN || "Texto teste" //Texto teste
</code></pre>
<p>Essa solução é realmente ótima quando queremos lidar com qualquer tipo que consideramos <strong>"Falsey"</strong></p>
<p>O <strong>Nullish Coalescing</strong> nos apresenta um operador de duas interrogações (??) que nos trás uma verificação mais <em>type strict p</em>ermitindo um valor <em>default</em> <strong>apenas</strong> quando temos um <em>null</em> ou <em>undefined</em>.</p>
<pre><code class="lang-plaintext">false ?? “Texto teste” // false
undefined ?? “Texto teste” // Texto teste
null ?? ”Texto teste” // Texto teste
NaN ?? “Texto teste” // NaN
</code></pre>
<p>Podemos simplificar o exemplo anterior desta forma:</p>
<pre><code class="lang-plaintext">user.profile.name == undefined ? “Anonymous” : person.profile.name
user.profile.name ?? “Anonymous”
</code></pre>
<p>Supondo que no nosso mesmo objeto <code>user</code>, podemos dentro de profile ter tanto um <code>name</code> quanto um <code>nickname.</code>Se em um campo de nome devo mostrar o <code>name</code> <strong>OU</strong> o<code>nickname</code> <strong>OU</strong> um valor padrão, nossa solução comum seria algo similar a:</p>
<pre><code class="lang-plaintext">if (person.profile.nickname == undefined) { 
  if(person.profile.name == undefined) {
    “Anonymous”
  } else {
    return person.profile.name
  }
} else {
  return person.profile.nickname
}
</code></pre>
<p>Com nosso novo operador se torna apenas:</p>
<pre><code class="lang-plaintext">person.profile.nickname ?? person.profile.name ?? “Anonymous”.
</code></pre>
<p>Essa sintaxe já é <a target="_blank" href="https://en.wikipedia.org/wiki/Null_coalescing_operator">bem conhecida</a> em outras linguagens como <em>C#</em> e <em>Swift,</em> está presente no <em>PHP</em> desde sua versão 7 e já está começando a ser implementada nos maiores navegadores.</p>
<p><strong>📖</strong><a target="_blank" href="https://tc39.es/proposal-nullish-coalescing/"><strong>Especificação</strong></a><strong>🗼</strong><a target="_blank" href="https://babeljs.io/docs/en/babel-plugin-proposal-nullish-coalescing-operator"><strong>Plugin Babel</strong></a></p>
<h1 id="heading-stringprotypematchallhttpsgithubcomtc39proposal-string-matchall"><a target="_blank" href="https://github.com/tc39/proposal-string-matchall"><strong>String.protype.matchAll</strong></a> <strong>💕</strong></h1>
<p>O novo metodo<code>matchAll()</code> está relacionado a expressões regulares.Ele recebe uma expressão como argumento e retorna um iterador com todos os resultados que deram "<em>match</em>" com essa expressão.</p>
<p>Podemos acessar os casos iterando o seu resultado.</p>
<pre><code class="lang-plaintext">const onlyABC = /[a-c]/g
const str = 'abc'
const matches = str.matchAll(onlyABC)for (const match of matches) {
  console.log(match);
}// ["a", index: 0, input: "abc", groups: undefined]
// ["b", index: 0, input: "abc", groups: undefined]
// ["c", index: 0, input: "abc", groups: undefined]
</code></pre>
<p>Após a interação pelo <em>for..of</em> nosso iterador fica cansado, então temos de chamar o <code>matchAll()</code> novamente se requeremos os resultados novamente.</p>
<pre><code class="lang-plaintext">const arrMatches = [...str.matchAll(onlyABC)]// [["a", index: 0, input: "abc", groups: undefined],
    ["b", index: 0, input: "abc", groups: undefined],
    ["c", index: 0, input: "abc", groups: undefined]]
</code></pre>
<p>Ok, mas qual o beneficio?Agora conseguimos <strong>um resultado mais complexo para nossa <em>regex</em> além do <em>match</em> em si</strong>, **e isso fica visível em casos mais complexos em temos diversos agrupamentos.</p>
<pre><code class="lang-plaintext">const getTest = /t(e)(st(\d?))/g;
const str = 'test1test2'const arrMatches= [...str.matchAll(getTest)];

array[0];
// ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
array[1];
// ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]str.match(getTest); 
// Array ['test1', 'test2']
</code></pre>
<p>A escolha de retornar um iterador é por uma mera questão de performance, já que podemos facilmente coletar esses valores por meio do <em>spread operador</em> como no exemplo acima.Essa feature já está também vastamente implementada.</p>
<p><strong>📖</strong><a target="_blank" href="https://tc39.es/proposal-string-matchall/"><strong>Especificação</strong></a></p>
<h1 id="heading-standardized-globalthis-object"><strong>Standardized globalThis object 🌍</strong></h1>
<p>O que para alguns é um monstro para outros pode ser benção, agora temos padronizado o <strong>THIS GLOBAL</strong>. Ou seja, um contexto da aplicação global independente de <em>runtime</em>.</p>
<p>O <code>globalThis</code> se refere ao objeto global, independente de onde você está executando o código. Sendo assim você pode em produção para um projeto multiplataforma escrever isso:</p>
<pre><code class="lang-plaintext">globalThis.variavelGlobalzassa = "Irraaa 🤠🐎"
</code></pre>
<p>Brincadeiras a parte, essa padronização se deve ao fato que por JS ser multiplataforma e portanto, um único código pode rodar no Node, no navegador ou em qualquer outro contexto.Sendo assim, fica difícil ter um objeto global sem uma padronização se isso vai ser em um <code>window</code> (Browser) ou<code>global</code> (Node) por exemplo.</p>
<p><strong>📖</strong><a target="_blank" href="https://tc39.es/proposal-global/"><strong>Especificação</strong></a></p>
<h1 id="heading-promiseallsettled"><strong>Promise.allSettled 🚦</strong></h1>
<p>O metodo<code>Promise.allSettled</code> recebe um <em>array</em> de <em>Promises</em> e só se resolve quando todas as elas estiverem resolvidas, seja como <em>fulfilled</em> ou *rejected,*com o estado de cada uma delas.</p>
<p>Ou seja, com ele podemos criar uma nova <em>Promise</em> que só retorna quando todas as <em>Promises</em> passadas forem concluídas, <strong>independente de resultado</strong>, sem a necessidade de um encadeamento.</p>
<p>O método retorna um <em>array</em> com o status das <em>Promises</em> com o seu respectivo valor, caso <em>fullfilled,</em> ou a razão da falha, caso <em>rejected</em>.</p>
<p>Nesse exemplo temos colocamos duas promises no <code>Promise.allSettled</code> , uma com resolução e outra com falha, e damos console.log no resultado!</p>
<pre><code class="lang-plaintext">const stuff1 = new Promise((res, rej) =&gt; res({x: 10, test: "🤠"}));
const stuff2= new Promise((res, rej) =&gt; rej(Error("Deu ruim 😭")));Promise.allSettled([stuff1, stuff2])
  .then(data =&gt; console.log(data)); 
// [ 
//   Object { status: "fulfilled", value: {x: 10, test: "🤠"}},
//   Object { status: "rejected", reason: "Deu ruim 😭"} 
// ]
</code></pre>
<p>Temos como resultado um array com dois objetos, ambos com o status de resolução da <em>Promise</em>. A que foi resolvida tem uma propriedade <code>value</code> que contêm o conteúdo da <em>Promise</em> e que falhou tem a propriedade **<code>reason</code><em>q</em>ue fala a razão do erro.</p>
<p>Já tentávamos fazer algo similar resolvendo múltiplas promises simultâneas com o <code>Promise.all</code> .</p>
<pre><code class="lang-plaintext">Promise.all([stuff1, stuff2])
  .catch(err =&gt; console.log(err));  // Deu ruim 😭
</code></pre>
<p>Se colocássemos as duas promises o <code>Promise.all</code> joga pra cima a falha do <code>stuff2</code>para que você trate e ignora completamente as <em>Promises</em> que foram resolvidas. <strong>Não tínhamos até então um método que “não ligasse” pros resultados de cada uma das <em>Promises</em>.</strong></p>
<p>A motivação vem da implementação dos <a target="_blank" href="https://v8.dev/features/promise-combinators">4 combinators de promises</a>, que são os principais casos implementados em bibliotecas ou linguagens para lidar com assincronismo.</p>
<p>Nele temos o <code>Promise.all</code> e o<code>Promise.race</code> que já foram especificados na <em>ES2015,</em> o <code>Promise.allSettled</code> , e um futuro metodo a ser incluído em uma <strong>próxima proposta</strong> chamado <code>Promise.any</code> .</p>
<p>O <code>Promise.any</code> receberia também uma lista de <em>Promises</em> e retornaria quando qualquer uma fosse resolvida.</p>
<p><strong>📖</strong><a target="_blank" href="https://tc39.es/proposal-promise-allSettled/"><strong>Especificação</strong></a></p>
<h1 id="heading-for-in-mechanicshttpsgithubcomtc39proposal-for-in-order"><a target="_blank" href="https://github.com/tc39/proposal-for-in-order"><strong>for-in mechanics</strong></a> <strong>🎡</strong></h1>
<p>Quem acompanhou as mudanças sabe da existência dessa feature. Aparentemente a especificação da forma como for-in deve ser implementada foi na verdade apenas mais refinada pois a sua ultima versão foi pouco especifica em relação a que ordem o <code>for (x in y)</code>deve rodar levando a <em>engines</em> não entraram em um consenso sobre como implementar.</p>
<p><strong>📖</strong><a target="_blank" href="http://tc39.es/proposal-for-in-order/"><strong>Especificação</strong></a></p>
<h1 id="heading-dynamic-import-importhttpsgithubcomtc39proposal-dynamic-import"><a target="_blank" href="https://github.com/tc39/proposal-dynamic-import"><strong>Dynamic Import / Import()</strong></a> <strong>🚢</strong></h1>
<p>O import dinâmico retorna uma uma promise para o objeto do modulo do namespace que foi requisitado. Sendo assim, <strong>agora poderemos colocar um import dentro de uma variável e chamar usando async/await .</strong></p>
<p>Para que isso é importante? Podemos importar nossos arquivos de forma “<em>Lazy</em>” ou seja, <strong>apenas executar código dos arquivos conforme queremos.</strong></p>
<p>Isso garante um controle da execução código muito maior em <em>runtime</em>podendo impactar muito na performance pois <strong>executar todos os arquivos que são importados imediatamente pode ser um <em>overhead.</em></strong></p>
<p>Se por exemplo, estou usando funções de utilidade de outro arquivo ou pacote que são utilizadas apenas algum momento especifico do meu código.<em>Será que faz sentido mais importá-las quando o arquivo foi executado ou quando forem(e se forem) realmente utilizadas?</em></p>
<pre><code class="lang-plaintext">//utils.js...muitas funções e coisas...const add = (x, y) =&gt; x + y;export { add };
</code></pre>
<p>Se estou fazendo uso dele em outro arquivo podemos importá-lo apenas antes de usar a função importada em especifico.</p>
<pre><code class="lang-plaintext">const doMathStuff = async (x, y) =&gt; {
    const math = await import('./utils.js');
    console.log(math.add(5, 10));
};
</code></pre>
<p>Em <em>runtime</em> essa função não vai ser carregada a não ser que chamada, portanto pode até mesmo <strong>nunca ser carregada se nunca for usada</strong>.</p>
<p>Isso é extremamente crucial por exemplo em <em>front-end</em> em que queremos minimizar o máximo possível o conteúdo sendo executado. Muito código sendo executado inconsequentemente ao abrir um site pode ser bem custoso*(<a target="_blank" href="https://medium.com/reloading/javascript-start-up-performance-69200f43b201">ver “V8 Start-up Performance”</a>).*</p>
<p>Isso é conhecido como <em>code splitting</em> e muito provávelmente seu código já está sendo pelo menos um pouco otimizado pelo próprio <em>babel</em> com <em>webpack</em>, ou qualquer outro <em>module bundle</em> dessa forma.</p>
<p>O <em>webpack</em> por exemplo faz algo chamado <a target="_blank" href="https://webpack.js.org/guides/tree-shaking/">"Tree shaking"</a> , em que ele basicamente monta uma arvore de dependências do seu próprio código e otimiza por exemplo, removendo o que não está sendo usado.</p>
<p>Os imports dinâmicos ficam de fora do <em>Tree Shaking</em> do <em>webpack</em> <em>(ver</em><a target="_blank" href="https://medium.com/better-programming/dynamic-import-and-tree-shaking-in-javascript-ddc2f3cd69f"><em>Dynamic Import and Tree Shaking in JavaScript</em></a><em>)</em>, então é importante questionar quando vale a pena deixar o controle na nossa mão ou em outras ferramentas.</p>
<p><strong>📖</strong><a target="_blank" href="https://github.com/tc39/proposal-export-default-from"><strong>Especificação</strong></a><strong>🗼</strong><a target="_blank" href="https://babeljs.io/docs/en/babel-plugin-proposal-export-default-from"><strong>Plugin babel</strong></a><strong>🌲</strong><a target="_blank" href="https://developers.google.com/web/fundamentals/performance/optimizing-javascript/tree-shaking"><strong>Otimização JS com tree shaking</strong></a></p>
<h1 id="heading-module-namespace-exportshttpsgithubcomtc39proposal-export-ns-from"><a target="_blank" href="https://github.com/tc39/proposal-export-ns-from"><strong>Module Namespace Exports</strong></a> <strong>🛄</strong></h1>
<p>Nos módulos podemos usar a seguinte sintaxe para importarmos todos os elementos de por exemplo, um arquivo <code>utils</code>:</p>
<pre><code class="lang-plaintext">import * from './utils.js'
</code></pre>
<p>Mas não podíamos exportar de forma similar <strong>nativamente</strong> e tínhamos de exportar o próprio modulo dentro de um objeto.</p>
<pre><code class="lang-plaintext">import default as utils from './utils.js'
export { utils }
</code></pre>
<p>Mas agora temos uma sintaxe similar para exportar todo o conteúdo do módulo de forma similar!</p>
<pre><code class="lang-plaintext">export * from './utils.js'
</code></pre>
<p>Também podemos renomear o conteúdo exportado como nos exemplos:</p>
<pre><code class="lang-plaintext">export * as utils from './utils.js'
export { add as soma } from  './utils.js'
</code></pre>
<p>A ideia é bem simples mas essa simetria deixa mais consistente a forma como lidamos com nossos projetos.</p>
<p><strong>📖</strong><a target="_blank" href="https://tc39.es/proposal-export-ns-from/"><strong>Especificação</strong></a><strong>🗼</strong><a target="_blank" href="https://babeljs.io/docs/en/babel-plugin-proposal-export-namespace-from"><strong>Plugin Babel</strong></a></p>
<p>— — — — —</p>
<p>"Quero usar essas funcionalidade tipo, <strong>AGORA</strong>!!"</p>
<p>Basta modificar o seu arquivo<code>.babelrc</code> alguns destes novos plugins</p>
<pre><code class="lang-plaintext">{
  "plugins": [
    "@babel/plugin-proposal-nullish-coalescing-operator",
    "@babel/plugin-proposal-optional-chaining",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-private-methods",
    "@babel/plugin-syntax-bigint"
  ]
}
</code></pre>
<p>Caso você não tenha nada configurado a forma mais simples seria usando o <a target="_blank" href="https://parceljs.org/">Parcel bundler</a> no seu projeto instalando-o como dependência</p>
<pre><code class="lang-plaintext">$ yarn add parcel-bundler
</code></pre>
<p>E em seguida configurando nos scripts do seu <em>package.json</em> para que ele execute os seu projeto.</p>
<pre><code class="lang-plaintext">// package.json..."scripts": {
  "start": "parcel index.js"
},
</code></pre>
<h1 id="heading-conclusao"><strong>Conclusão</strong></h1>
<p><strong>Javascript é uma linguagem viva</strong> e vemos nos últimos anos uma evolução constante para melhorar o desenvolvimento web e isso certamente é uma tarefa difícil para uma uma comunidade também crescendo e evoluindo muito rápido com a linguagem.</p>
<p>Espero que vocês tenham gostado!! 👏 👏 👏 👏 👏 👏</p>
<p>**Quem gostou bate palminha pra que o artigo alcance outros amiguinhos.**<em>❤️🧡💛💚💙💜.</em></p>
<p><a target="_blank" href="https://github.com/tc39/proposals/blob/master/finished-proposals.md">https://github.com/tc39/proposals/blob/master/finished-proposals.md</a></p>
]]></content:encoded></item></channel></rss>