<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://posix.dev.br/feed.xml" rel="self" type="application/atom+xml" /><link href="https://posix.dev.br/" rel="alternate" type="text/html" /><updated>2024-09-22T23:03:38+00:00</updated><id>https://posix.dev.br/feed.xml</id><title type="html">daniel @ posixtronic</title><subtitle>Data, systems and computers</subtitle><entry><title type="html">JavaScript: promises, thenables, async/await</title><link href="https://posix.dev.br/blog/javascript-promises-thenables-async" rel="alternate" type="text/html" title="JavaScript: promises, thenables, async/await" /><published>2021-05-02T00:00:00+00:00</published><updated>2021-05-02T00:00:00+00:00</updated><id>https://posix.dev.br/blog/javascript-promises-thenables-async</id><content type="html" xml:base="https://posix.dev.br/blog/javascript-promises-thenables-async">&lt;p&gt;A JavaScript é a linguagem do frontend da Web, um ambiente com frequentes operações de IO e computações paralelas. A programação assíncrona é bastante comum em aplicações JavaScript. Apresento recursos de assincronismo da JS acompanhados de exemplos elementares de sua utilização.&lt;/p&gt;

&lt;!--more--&gt;

&lt;!-- TOC GFM --&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#promessas&quot;&gt;Promessas&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#thenables&quot;&gt;Thenables&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#async&quot;&gt;Async&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#await&quot;&gt;Await&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#ver-também&quot;&gt;Ver também&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;!-- /TOC --&gt;

&lt;h2 id=&quot;promessas&quot;&gt;Promessas&lt;/h2&gt;

&lt;p&gt;Promessas são objetos que quando resolvidos retornam um valor para a condição de &lt;strong&gt;sucesso&lt;/strong&gt; ou outro para uma de &lt;strong&gt;falha&lt;/strong&gt;. Dessa forma uma promessa é um objeto que possui um &lt;strong&gt;estado&lt;/strong&gt; e um &lt;strong&gt;valor&lt;/strong&gt; e que está associado a métodos que o &lt;strong&gt;resolvem&lt;/strong&gt; ou o &lt;strong&gt;rejeitam&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// cria um objeto p do tipo promessa&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// resolve a promessa retornando um valor aleatório de par ou ímpar&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Par&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Ímpar&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//  rejeita a promessa em caso de erro&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;thenables&quot;&gt;Thenables&lt;/h2&gt;
&lt;p&gt;Um &lt;strong&gt;thenable&lt;/strong&gt; é um objeto com o método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then(onFullfiled[, onRejected])&lt;/code&gt;. Toda promessa é um thenable e como o método retorna uma promessa, ele é utilizado para encadear operações.&lt;/p&gt;

&lt;p&gt;Outros métodos são o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;catch(onRejected)&lt;/code&gt; e o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finally(onSettled)&lt;/code&gt;. Onde &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;catch(onCatch)&lt;/code&gt; é equivalente a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then(onThen, onCatch)&lt;/code&gt; e &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finally(onFinally)&lt;/code&gt; é equivalente a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then(onFinally, onFinally)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Nota: As funções ‘on…’ não são built-ins mas identificadores arbitrários que escolhi para representar os respectivos callbacks.&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Requisita a URL e passa o texto da página para uma função callback&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;https://www.google.com/robots.txt&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; 
&lt;span class=&quot;nf&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Nota: Devido à política de CORS dos navegadores. Solicitações de recursos em endereços externos ao domínio da página são bloqueados. Em outras palavras, você precisa estar em site.com para solicitar um recurso em site.com.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O callback, um pedaço de código executável que é passado como argumento e executado futuramente, é a essência da programaçao assíncrona. No caso um callback é uma função que é passada como argumento para o método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.then()&lt;/code&gt; e executada tendo o valor contido na promessa passado como argumento.&lt;/p&gt;

&lt;p&gt;O callback é uma função qualquer que não seja um método. A exemplo:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Armazena e imprime o texto da página&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;printText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;https://www.google.com/robots.txt&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; 
&lt;span class=&quot;nf&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// imprime o texto da página&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// imprime um eventual erro&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;async&quot;&gt;Async&lt;/h2&gt;
&lt;p&gt;O &lt;strong&gt;async&lt;/strong&gt; é uma palavra-chave que faz com que a função seja executada sem bloqueio.&lt;/p&gt;

&lt;p&gt;A invocação da função não cria uma promessa todavia o seu retorno, caso não seja uma promessa, é embrulhado como uma promessa resolvida. E caso não haja retorno, ela retorna uma promessa resolvida cujo valor é indefinido.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// retorna uma promessa resolvida cuja valor é 0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;nihil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;await&quot;&gt;Await&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;await&lt;/strong&gt; aguarda a resolução de uma promessa. Ele pausa a execução da função até que a promessa seja resolvida ou recusada e desembrulha uma promessa resolvida. Se o async é o &lt;strong&gt;yin&lt;/strong&gt;, o await é o &lt;strong&gt;yang&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ele não é sempre necessário mas é utilizado para evitar uma condição de corrida ou para desembrulhar uma promessa. A restrição é que ele apenas pode ser utilizado dentro de uma função async.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Aguarda 1s e imprime um valor&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;countSec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resolve&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
     &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Conta de 1 a 5s&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;playHideSeek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Vamos brincar de esconde-esconde...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// o await impede a condição de corrida&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;countSec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Tô indo heim!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;playHideSeek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Requisita a URL e imprime dados JSON de uma API&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;https://jsonplaceholder.typicode.com/todos/1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fetchData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// sem o await acima, imprime-se a promessa&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;fetchData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;ver-também&quot;&gt;Ver também&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://medium.com/trainingcenter/entendendo-promises-de-uma-vez-por-todas-32442ec725c2&quot;&gt;Entendendo promises de uma vez por todas&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bevacqua.github.io/promisees/&quot;&gt;Promisees&lt;/a&gt;: playground para visualização de promesas&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://jakearchibald.com/2017/await-vs-return-vs-return-await/&quot;&gt;await, return, return await&lt;/a&gt;: um comparativo&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><category term="javascript" /><category term="async" /><summary type="html">A JavaScript é a linguagem do frontend da Web, um ambiente com frequentes operações de IO e computações paralelas. A programação assíncrona é bastante comum em aplicações JavaScript. Apresento recursos de assincronismo da JS acompanhados de exemplos elementares de sua utilização.</summary></entry><entry><title type="html">Youtube without fuss on Android</title><link href="https://posix.dev.br/blog/youtube-android-without-fuss" rel="alternate" type="text/html" title="Youtube without fuss on Android" /><published>2021-04-26T00:00:00+00:00</published><updated>2021-04-26T00:00:00+00:00</updated><id>https://posix.dev.br/blog/youtube-android-without-fuss</id><content type="html" xml:base="https://posix.dev.br/blog/youtube-android-without-fuss">&lt;p&gt;How to watch Youtube videos without ads and interruption besides subscribing to it?&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The orthodox solution is to use &lt;a href=&quot;https://github.com/YTVanced&quot;&gt;Youtube Vanced&lt;/a&gt;. It works perfectly, it’s Youtube Premium with all it’s features plus more and for free. Although it comes with a price. While I think it is fully open-source, you still have to install multiple binaries from outside the store. And in my case there was suspicious high battery usage from those apps even when they weren’t opened for days. A red flag and at least a problem for practical reasons.&lt;/p&gt;

&lt;p&gt;The alternative that I found most straight forward was to simply use &lt;a href=&quot;https://play.google.com/store/apps/details?id=org.mozilla.firefox&quot;&gt;Firefox for Android&lt;/a&gt; coupled with &lt;a href=&quot;https://github.com/gorhill/uBlock#ublock-origin&quot;&gt;uBlock Origin&lt;/a&gt; and &lt;a href=&quot;https://github.com/mozilla/video-bg-play&quot;&gt;Video Background Play Fix&lt;/a&gt; addons. Not as nice as Vanced but works without fuss.&lt;/p&gt;</content><author><name></name></author><category term="youtube" /><category term="android" /><summary type="html">How to watch Youtube videos without ads and interruption besides subscribing to it?</summary></entry><entry><title type="html">Migrando para o Zsh e o Zinit</title><link href="https://posix.dev.br/blog/zsh-zinit" rel="alternate" type="text/html" title="Migrando para o Zsh e o Zinit" /><published>2021-04-22T00:00:00+00:00</published><updated>2021-04-22T00:00:00+00:00</updated><id>https://posix.dev.br/blog/zsh-zinit</id><content type="html" xml:base="https://posix.dev.br/blog/zsh-zinit">&lt;p&gt;O &lt;a href=&quot;https://www.zsh.org/&quot;&gt;Zsh&lt;/a&gt; é o mais avançado e performático dos interpretadores shell e o &lt;a href=&quot;https://github.com/zdharma/zinit&quot;&gt;Zinit&lt;/a&gt; é o mais avançado e performático dos gerenciadores de plugins para o Zsh.  A seguir mostro como migrar para o Zsh e realizar uma configuração simples porém funcional utilizando o Zinit com completações, sugestões automáticas, destaque de sintaxe e o Powerlevel10k.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;por-que-migrar&quot;&gt;Por que migrar?&lt;/h2&gt;
&lt;p&gt;O Zsh é superior. Não há desvantagens em utilizá-lo, só vantagens. Você pode perder uma ou outra funcionalidade que o Fish entrega sem necessidade de configuração mas provavelmente haverá um plugin para o Zsh com essa funcionalidade e no fim do dia você vai estar em um interpretador robusto com mais recursos de linguagem, performance superior à de seus concorrentes e que possui um grande número de usuários e extensões.&lt;/p&gt;

&lt;p&gt;Devido ao Zinit ser assíncrono, o tempo de carregamento é menor ao utilizá-lo do que ao carregar diretamente os plugins. Entretanto a principal vantagem em utilizar um gerenciador de plugins não está na rapidez mas na portabilidade. O setup do usuário passa a independer do gerenciador de pacotes do sistema e os &lt;a href=&quot;https://github.com/lbcnz/dotfiles&quot;&gt;dotfiles&lt;/a&gt; podem ser clonados e utilizados, a princípio, sem necessidade de modificação em qualquer outro sistema operacional que disponibilize o Zsh como shell. É até mesmo possível configurar para que o Zinit instale, caso não os encontre, programas como o fzf, que são bastante utilizados por usuários mas não omnipresentes nos sistemas.&lt;/p&gt;

&lt;h2 id=&quot;instruções&quot;&gt;Instruções&lt;/h2&gt;

&lt;h4 id=&quot;setar-o-zsh-como-interpretador-shell-de-login&quot;&gt;Setar o Zsh como interpretador shell de login.&lt;/h4&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;chsh &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;which zsh&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;renomear-o-arquivo-de-configuração-padrão-zshrc-do-zsh&quot;&gt;Renomear o arquivo de configuração padrão, ‘.zshrc’, do Zsh&lt;/h4&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;mv&lt;/span&gt; ~/.zshrc ~/.zshrc.old
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Obs: O Zinit muda a forma como completações são carregadas e a configuração padrão do Zsh é desnecessária e indesejada.&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;criar-um-novo-zshrc&quot;&gt;Criar um novo ‘.zshrc’.&lt;/h4&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Instant Prompt&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# --------------&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;XDG_CACHE_HOME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/.cache&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/p10k-instant-prompt-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%n&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.zsh&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ZELLIJ&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;XDG_CACHE_HOME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/.cache&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/p10k-instant-prompt-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%n&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.zsh&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Zinit&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -----&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-A&lt;/span&gt; ZINIT
ZINIT[BIN_DIR]&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$XDG_CONFIG_HOME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/zsh/zinit/bin&quot;&lt;/span&gt;
ZINIT[HOME_DIR]&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$XDG_CONFIG_HOME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/zsh/zinit&quot;&lt;/span&gt;
ZINIT[ZCOMPDUMP_PATH]&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$XDG_DATA_HOME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/shell/zcompdump&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ZINIT&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[BIN_DIR]/zinit.zsh&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# instalar se não encontrado&lt;/span&gt;
    git clone &lt;span class=&quot;nt&quot;&gt;--depth&lt;/span&gt; 1 &lt;span class=&quot;nt&quot;&gt;--branch&lt;/span&gt; master &lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/zdharma/zinit&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ZINIT&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[BIN_DIR]&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ZINIT&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[BIN_DIR]/zinit.zsh&quot;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# carregar&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Prompt&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Utilizar prompt arco-íris se em um terminal burro&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TERM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; linux &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;autoload &lt;span class=&quot;nt&quot;&gt;-U&lt;/span&gt; colors &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; colors
    &lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PS1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%B%{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fg&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[yellow]%}%n%{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fg&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[green]%}@%{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fg&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[blue]%}%M %{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fg&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[magenta]%}%~%{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$reset_color&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;%} &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$%&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;b &quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Do contrário, utilizar o Powerlevel10k se setar um título contextual à janela&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else
    &lt;/span&gt;zinit &lt;span class=&quot;nv&quot;&gt;depth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        load &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
            romkatv/powerlevel10k &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        is-snippet &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$XDG_CONFIG_HOME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/zsh/p10k.zsh&quot;&lt;/span&gt;
	
    &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;x_title_precmd &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        print &lt;span class=&quot;nt&quot;&gt;-Pn&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\e]2;%n@%m %~\a'&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TERM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'screen'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; print &lt;span class=&quot;nt&quot;&gt;-Pn&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\e_\005{g}%n\005{-}@\005{m}%m\005{-} \005{B}%~\005{-}\e\\'&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;x_title_preexec &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        print &lt;span class=&quot;nt&quot;&gt;-Pn&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\e]2;%n@%m %~ %# '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; print &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(q)1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\a&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TERM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'screen'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; print &lt;span class=&quot;nt&quot;&gt;-Pn&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\e_\005{g}%n\005{-}@\005{m}%m\005{-} \005{B}%~\005{-} %# '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; print &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(q)1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\e\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    add-zsh-hook &lt;span class=&quot;nt&quot;&gt;-Uz&lt;/span&gt; precmd x_title_precmd
	add-zsh-hook &lt;span class=&quot;nt&quot;&gt;-Uz&lt;/span&gt; preexec x_title_preexec
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Plugins&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -------&lt;/span&gt;
zinit &lt;span class=&quot;nb&quot;&gt;wait &lt;/span&gt;lucid &lt;span class=&quot;nv&quot;&gt;depth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    atinit&lt;span class=&quot;s2&quot;&gt;&quot;zicompinit; zicdreplay&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        zdharma/fast-syntax-highlighting &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    atload&lt;span class=&quot;s2&quot;&gt;&quot;_zsh_autosuggest_start&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        zsh-users/zsh-autosuggestions &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    blockf atpull&lt;span class=&quot;s1&quot;&gt;'zinit creinstall -q .'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        zsh-users/zsh-completions &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Extra&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -----&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Utilizar menu de seleção para completações&lt;/span&gt;
zstyle &lt;span class=&quot;s1&quot;&gt;':completion:*'&lt;/span&gt; menu &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;iniciar-uma-nova-sessão&quot;&gt;Iniciar uma nova sessão&lt;/h3&gt;

&lt;p&gt;Aproveite as novas funcionalidades:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Comandos são colorizados sintaticamente;&lt;/li&gt;
  &lt;li&gt;TAB uma vez completa um comando ou expande as opções quando há mais de uma;&lt;/li&gt;
  &lt;li&gt;TAB duas vezes abre um menu para navegar entre as opções de completação;&lt;/li&gt;
  &lt;li&gt;Sugestões são recomendadas com base no histórico de comandos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E se quiser mais ideias para customizar o seu sistema, confira este repositório com as &lt;a href=&quot;https://github.com/lbcnz/dotfiles&quot;&gt;minhas configurações&lt;/a&gt;.&lt;/p&gt;</content><author><name></name></author><category term="shell" /><category term="zsh" /><category term="dotfiles" /><summary type="html">O Zsh é o mais avançado e performático dos interpretadores shell e o Zinit é o mais avançado e performático dos gerenciadores de plugins para o Zsh. A seguir mostro como migrar para o Zsh e realizar uma configuração simples porém funcional utilizando o Zinit com completações, sugestões automáticas, destaque de sintaxe e o Powerlevel10k.</summary></entry><entry><title type="html">Extensões para navegador</title><link href="https://posix.dev.br/blog/extensoes-navegador" rel="alternate" type="text/html" title="Extensões para navegador" /><published>2021-04-20T00:00:00+00:00</published><updated>2021-04-20T00:00:00+00:00</updated><id>https://posix.dev.br/blog/extensoes-navegador</id><content type="html" xml:base="https://posix.dev.br/blog/extensoes-navegador">&lt;p&gt;Apresento algumas extensões de navegador que utilizo a fim de extender funcionalidades e melhorar minha produtividade e privacidade. A grande maioria é open-source e suporta tanto o Chromium e o Firefox.&lt;/p&gt;

&lt;!--more--&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#privacidade&quot;&gt;Privacidade&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#utilidade&quot;&gt;Utilidade&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#produtividade&quot;&gt;Produtividade&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#observação&quot;&gt;Observação&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;privacidade&quot;&gt;Privacidade&lt;/h2&gt;
&lt;h3 id=&quot;ublock-origin&quot;&gt;&lt;a href=&quot;https://github.com/gorhill/uBlock&quot;&gt;uBlock Origin&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Bloqueia anúncios, scripts maliciosos, rastreadores e outras coisas que não agregam em nada enquanto distraem o usuário e aumentam o tempo de carregamento da página. Ele também pode ser utilizado agressivamente, bloqueando scripts e fontes web para certos sites ou globalmente.&lt;/p&gt;

&lt;h3 id=&quot;clearurls&quot;&gt;&lt;a href=&quot;https://clearurls.xyz/&quot;&gt;ClearURLS&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Remove parâmetros de rastreio de URLs.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://www.amazon.com.br/guia-mochileiro-das-gal%C3%A1xias-ebook/dp/B00A3D9OF6/ref=sr_1_1?dchild=1&amp;amp;keywords=o+guia+do+mochileiro+das+gal%C3%A1xias&amp;amp;qid=1618948820&amp;amp;s=books&amp;amp;sr=1-1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Vira:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://www.amazon.com.br/guia-mochileiro-das-gal%C3%A1xias-ebook/dp/B00A3D9OF6&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;decentraleyes&quot;&gt;&lt;a href=&quot;https://decentraleyes.org/&quot;&gt;Decentraleyes&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Intercepta requisições de recursos em CDNs e os serve localmente. O que reduz o tempo de carregamento por eliminar uma requisição inútil e impede que o CDN seja utilizado para rastreio.&lt;/p&gt;

&lt;h3 id=&quot;https-everywhere&quot;&gt;&lt;a href=&quot;https://www.eff.org/pt-br/https-everywhere&quot;&gt;HTTPS Everywhere&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Faz o upgrade&lt;/em&gt;, reescreve, requisições HTTP para HTTPS. Requisições HTTP não são encriptadas e qualquer um com a capacidade de interceptar o tráfego de rede tem acesso ao conteúdo das mensagens. No protocolo HTTPS o usuário tem as garantia da privacidade dos seus dados e da autenticidade do site.&lt;/p&gt;

&lt;h3 id=&quot;useragent-switcher&quot;&gt;&lt;a href=&quot;https://github.com/ray-lothian/UserAgent-Switcher/&quot;&gt;UserAgent Switcher&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Permite spoofar a identidade do navegador. Pode ser utilizada para privacidade, para limitar o fingerprinting ou mesmo para burlar alguma restrição. A exemplo: &lt;em&gt;“esse site só roda no navegador X, sistema operacional Y, versão Z”&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;utilidade&quot;&gt;Utilidade&lt;/h2&gt;
&lt;h3 id=&quot;vimium&quot;&gt;&lt;a href=&quot;https://github.com/philc/vimium&quot;&gt;Vimium&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Permite navegar pela Internet utilizando apenas o teclado. Não é 100% pois, inevitavelmente, conflita com atalhos de teclado dos sites e não funciona, devido a politicas de segurança, nas URLs do tipo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chrome://.*&lt;/code&gt;. No entanto na maior parte do tempo evita o uso do mouse e tem uma curva de aprendizado pequena para quem já está acostumado com atalhos de teclado. Agora, infelizmente, ela não implementa os recursos de edições de texto do Vim.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;tecla&lt;/th&gt;
      &lt;th&gt;função&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;?&lt;/td&gt;
      &lt;td&gt;mostrar ajuda&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;o&lt;/td&gt;
      &lt;td&gt;abrir URL&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;O&lt;/td&gt;
      &lt;td&gt;abrir URL em nova aba&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;f, F&lt;/td&gt;
      &lt;td&gt;abrir link&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;x&lt;/td&gt;
      &lt;td&gt;fechar aba&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;X&lt;/td&gt;
      &lt;td&gt;reabrir aba&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;j, k, d, u&lt;/td&gt;
      &lt;td&gt;scroll&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;gg, G&lt;/td&gt;
      &lt;td&gt;início/fim&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;J, K&lt;/td&gt;
      &lt;td&gt;navegar entre abas&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;H, L&lt;/td&gt;
      &lt;td&gt;recuar e avançar&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Uma solução para minimizar o último problema é utilizar a extensão &lt;a href=&quot;https://github.com/jimschubert/NewTab-Redirect&quot;&gt;New Tab Redirect&lt;/a&gt;. Novas abas não abrirão páginas especiais e o Vimium funcionará sem problemas. Execções podem ser adicionadas para sites em que se deseja preservar os atalhos e os &lt;em&gt;binds&lt;/em&gt; convencionais do Chromium podem ser utilizados nesses momentos.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;tecla&lt;/th&gt;
      &lt;th&gt;função&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;^t&lt;/td&gt;
      &lt;td&gt;abrir aba&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;^w&lt;/td&gt;
      &lt;td&gt;fechar aba&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;^[1,2…9]&lt;/td&gt;
      &lt;td&gt;ir para aba&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;bypass-paywalls&quot;&gt;&lt;a href=&quot;https://github.com/iamadamdev/bypass-paywalls-chrome&quot;&gt;Bypass Paywalls&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Contorna automaticamente barreiras para visualização de conteúdo em centenas de sites.&lt;/p&gt;

&lt;h3 id=&quot;google-translate&quot;&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/google-translate/aapbdbdomjkkjkaonfhkkikfgjllcleb&quot;&gt;Google Translate&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Quebra o galho e evita ter de abrir uma nova aba quando é necessário traduzir trechos de um idioma do qual não entendo nada, como o mandarim. Basta selecionar o trecho e clicar no botão que aparece.&lt;/p&gt;

&lt;h3 id=&quot;highlighter&quot;&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/highlighter/fdfcjfoifbjplmificlkdfneafllkgmn&quot;&gt;Highlighter&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Permite marcar texto em páginas. As marcações são persistentes entre sessões.&lt;/p&gt;

&lt;h3 id=&quot;improved-youtube&quot;&gt;&lt;a href=&quot;https://improvedtube.com/&quot;&gt;Improved Youtube&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Possibilita customizar a interface do Youtube, maximizar o tamanho do player e esconder seções como comentários e recomendados.&lt;/p&gt;

&lt;h3 id=&quot;markdown-here&quot;&gt;&lt;a href=&quot;https://markdown-here.com/&quot;&gt;Markdown Here&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Permite escrever texto em Markdown e convertê-lo para HTML ao pressionar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CTRL + ALT + M&lt;/code&gt;. Suporta &lt;em&gt;code fences&lt;/em&gt; e tudo mais. A exemplo, pode ser utilizado para enviar mensagens de e-mail em texto rico.&lt;/p&gt;

&lt;h3 id=&quot;dark-reader&quot;&gt;&lt;a href=&quot;https://darkreader.org&quot;&gt;Dark Reader&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Converte sites para o modo escuro. Possui várias opções de customização como brilho, contraste e saturação. Permite salvar configurações globais e por site, entre outros.&lt;/p&gt;

&lt;h2 id=&quot;produtividade&quot;&gt;Produtividade&lt;/h2&gt;
&lt;h3 id=&quot;news-feed-eradicator&quot;&gt;&lt;a href=&quot;https://github.com/jordwest/news-feed-eradicator&quot;&gt;News Feed Eradicator&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Oculta o feed de redes sociais como Facebook e Twitter sem impactar em demais funcionalidades. Permite configurar em quais redes ocultar.&lt;/p&gt;

&lt;p&gt;Feeds infinitos são uma grande distração. São péssimos para se informar pois conteúdo já visto não é ocultado, na maior parte o conteúdo não é interessante e é ordenado por algoritmos bizarrros. Todavia maximizam o tempo de visualização dos anúncios e pra plataforma é isso que importa. É aquela velha estória, de que se você não tá pagando é porque você é o produto.&lt;/p&gt;

&lt;p&gt;Eu recomendo o uso no lugar de um agregador RSS. TT-RSS e RSSHub são uma boa combinação e podem ser instalados no Docker. E para aqueles que não querem trabalho, o &lt;a href=&quot;https://nodetics.com/feedbro/&quot;&gt;Feedbro&lt;/a&gt; é uma extensão de navegador e uma alternativa muito mais prática.&lt;/p&gt;

&lt;h3 id=&quot;ublacklist&quot;&gt;&lt;a href=&quot;https://github.com/iorate/uBlacklist&quot;&gt;uBlacklist&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Ela oculta e destaca resultados de busca utilizando expressões regulares. Um uso clássico é ocultar sites com ótimo SEO mas conteúdo de baixa qualidade e destacar sites como a Wikipédia e o StackOverflow.&lt;/p&gt;

&lt;h3 id=&quot;simple-bookmark-count&quot;&gt;&lt;a href=&quot;https://github.com/enoeda/uber_simple_bookmark_count&quot;&gt;Simple bookmark count&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Exibe no ícone o número de favoritos salvos.&lt;/p&gt;

&lt;h3 id=&quot;accelereader&quot;&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/accelereader-power-up-you/ndaldjfflhocdageglcnflfanmdhgfbi&quot;&gt;AcceleReader&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Estende as funcionalidades do &lt;a href=&quot;https://getpocket.com/&quot;&gt;Pocket&lt;/a&gt; e entre outros exibe no ícone o número de artigos a serem lidos e também gera um gráfico burn-out.&lt;/p&gt;

&lt;h2 id=&quot;observação&quot;&gt;Observação&lt;/h2&gt;
&lt;p&gt;Todas as extensões apresentadas acima são de código aberto com exceção de:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Google Translate&lt;/li&gt;
  &lt;li&gt;Highlighter&lt;/li&gt;
  &lt;li&gt;AcceleReader&lt;/li&gt;
  &lt;li&gt;Feedbro&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><category term="browser" /><category term="productivity" /><summary type="html">Apresento algumas extensões de navegador que utilizo a fim de extender funcionalidades e melhorar minha produtividade e privacidade. A grande maioria é open-source e suporta tanto o Chromium e o Firefox.</summary></entry></feed>