<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Thomas Belin</title>
  <subtitle>Freelance Front-End Architect in Paris. I leave code cleaner than I found it. Seriously into Functional and Reactive Programming.</subtitle>
  <link href="https://blog.atomrc.dev/feed.xml" rel="self"/>
  <link href="https://blog.atomrc.dev"/>
  <updated>2023-01-21T00:00:00Z</updated>
  <id>https://blog.atomrc.dev</id>
  <author>
    <name>Thomas Belin</name>
    <uri>https://twitter.com/atomrc</uri>
  </author>
  
  <entry>
    <title>Compiling your TypeScript library (2023 edition)</title>
    <link href="https://blog.atomrc.dev/p/typescript-library-compilation-2023/"/>
    
    <updated>2023-01-21T00:00:00Z</updated>
    
    <published>2023-01-21T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/typescript-library-compilation-2023/</id>
    <content type="html">&lt;style&gt;
    .winner {color: green;}
    .loser {color: red;}
&lt;/style&gt;
&lt;p&gt;When we talk about compiling TypeScript projects there are usually two different contexts that are often mixed together: compiling a library vs compiling an application.&lt;/p&gt;
&lt;p&gt;Those two contexts have slightly different constraints and need to be considered separately.&lt;/p&gt;
&lt;p&gt;Today I&#39;m going to focus on &lt;strong&gt;compiling a TypeScript library into a JavaScript package&lt;/strong&gt; :)&lt;/p&gt;
&lt;h2 id=&quot;the-wishlist&quot; tabindex=&quot;-1&quot;&gt;The wishlist&lt;/h2&gt;
&lt;p&gt;In order to build a nice library that is suited for most projects, we want our package to be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;type-checked when consumed in a TypeScript project;&lt;/li&gt;
&lt;li&gt;consumable in both &lt;code&gt;commonjs&lt;/code&gt; and &lt;code&gt;esmodule&lt;/code&gt; projects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;According to those wishes, we need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;generate and package the declaration files (&lt;code&gt;.d.ts&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;be able to compile for different module targets.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;considered-solutions&quot; tabindex=&quot;-1&quot;&gt;Considered solutions&lt;/h2&gt;
&lt;p&gt;Today, we are going to benchmark the following solutions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/compiler-options.html&quot;&gt;tsc&lt;/a&gt; - the native TypeScript compiler&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://esbuild.github.io/&quot;&gt;esbuild&lt;/a&gt; - a full-fledged bundler and superfast compiler written in &lt;code&gt;go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://swc.rs/&quot;&gt;swc&lt;/a&gt; - a full-fledged bundler and superfast compiler written in &lt;code&gt;rust&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tsup.egoist.dev/&quot;&gt;tsup&lt;/a&gt; - a TypeScript library builder based on &lt;code&gt;esbuild&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Side note: I have excluded tools that are only bundlers (&lt;code&gt;webpack&lt;/code&gt;, &lt;code&gt;rollup&lt;/code&gt;, ...) and &lt;code&gt;babel&lt;/code&gt; which was superseded by &lt;code&gt;swc&lt;/code&gt; and &lt;code&gt;esbuild&lt;/code&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;compiler&lt;/th&gt;
&lt;th&gt;&lt;code&gt;d.ts&lt;/code&gt; generation&lt;/th&gt;
&lt;th&gt;multiple module targets&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;esbuild&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;swc&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tsc&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tsup&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;By comparing features, there is already something that stands out: &lt;strong&gt;only &lt;code&gt;tsup&lt;/code&gt; can generate declarations files (&lt;code&gt;.d.ts&lt;/code&gt;) and target multiple package type out of the box&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is not a showstopper, though!&lt;br /&gt;
Nothing is preventing us from running the compilation twice for different module targets.&lt;br /&gt;
And for the &lt;code&gt;d.ts&lt;/code&gt; generation, we could rely on &lt;code&gt;tsc --emitDeclarationOnly&lt;/code&gt; to generate them for us.
(Both are actually what &lt;code&gt;tsup&lt;/code&gt; is doing under the hood).&lt;br /&gt;
It&#39;s worth noting that those processes do not step on each other&#39;s toes, so we could run both compilation in parallel :)&lt;/p&gt;
&lt;p&gt;Here would be the equivalent commands for all the tools we are going to evaluate:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;esbuild&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;esbuild src/*.ts &lt;span class=&quot;token parameter variable&quot;&gt;--format&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;esm &lt;span class=&quot;token parameter variable&quot;&gt;--outdir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;./lib/esm &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
esbuild src/*.ts &lt;span class=&quot;token parameter variable&quot;&gt;--format&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;cjs &lt;span class=&quot;token parameter variable&quot;&gt;--outdir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;./lib/cjs &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
tsc &lt;span class=&quot;token parameter variable&quot;&gt;--emitDeclarationOnly&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--outDir&lt;/span&gt; ./lib/types&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;tsup&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;tsup src/*.ts &lt;span class=&quot;token parameter variable&quot;&gt;--format&lt;/span&gt; esm,cjs &lt;span class=&quot;token parameter variable&quot;&gt;--dts&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;./lib&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;swc&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;swc &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;module.type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;es6 src/*.ts &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; ./lib/esm &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
swc &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;module.type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;commonjs src/*.ts &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; ./lib/cjs &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
tsc &lt;span class=&quot;token parameter variable&quot;&gt;--emitDeclarationOnly&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--outDir&lt;/span&gt; ./lib/types&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;tsc&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;tsc &lt;span class=&quot;token parameter variable&quot;&gt;--module&lt;/span&gt; esnext &lt;span class=&quot;token parameter variable&quot;&gt;--outDir&lt;/span&gt; ./lib/esm &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
tsc &lt;span class=&quot;token parameter variable&quot;&gt;--module&lt;/span&gt; commonjs &lt;span class=&quot;token parameter variable&quot;&gt;--outDir&lt;/span&gt; ./lib/cjs&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;benchmark&quot; tabindex=&quot;-1&quot;&gt;Benchmark&lt;/h2&gt;
&lt;p&gt;This benchmark will be all but scientific!&lt;br /&gt;
I just tested compiling a library that has a single TypeScript file on GitHub CI. Every compiler is run 30 times, which mean we have very little samples.&lt;br /&gt;
This is just to give us a rough idea of how they could perform.&lt;br /&gt;
Please take this benchmark with a grain of salt!&lt;/p&gt;
&lt;p&gt;(Here are the &lt;a href=&quot;https://github.com/atomrc/ts-lib-benchmark&quot;&gt;benchmark sources&lt;/a&gt; and the &lt;a href=&quot;https://github.com/atomrc/ts-lib-benchmark/actions&quot;&gt;results on Github Actions&lt;/a&gt;)&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;compiler&lt;/th&gt;
&lt;th&gt;min&lt;/th&gt;
&lt;th&gt;mean&lt;/th&gt;
&lt;th&gt;max&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;esbuild&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;winner&quot;&gt;1704ms&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;winner&quot;&gt;1812ms&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;2365ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;swc&lt;/td&gt;
&lt;td&gt;1794ms&lt;/td&gt;
&lt;td&gt;1855ms&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;winner&quot;&gt;1908ms&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tsup&lt;/td&gt;
&lt;td&gt;2001ms&lt;/td&gt;
&lt;td&gt;2034ms&lt;/td&gt;
&lt;td&gt;2085ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tsc&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;loser&quot;&gt;2160ms&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;loser&quot;&gt;2215ms&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;loser&quot;&gt;2420ms&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Just to highlight how generating &lt;code&gt;d.ts&lt;/code&gt; with &lt;code&gt;tsc&lt;/code&gt; is costly, here is the same benchmark in which we skip generating declaration files:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;compiler (no &lt;code&gt;d.ts&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;min&lt;/th&gt;
&lt;th&gt;mean&lt;/th&gt;
&lt;th&gt;max&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;esbuild&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;winner&quot;&gt;414ms&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;winner&quot;&gt;427ms &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;winner&quot;&gt;500ms&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;swc&lt;/td&gt;
&lt;td&gt;537ms&lt;/td&gt;
&lt;td&gt;550ms&lt;/td&gt;
&lt;td&gt;570ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tsup&lt;/td&gt;
&lt;td&gt;559ms&lt;/td&gt;
&lt;td&gt;570ms&lt;/td&gt;
&lt;td&gt;587ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tsc&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;loser&quot;&gt;2119ms&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;loser&quot;&gt;2196ms&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class=&quot;loser&quot;&gt;2783ms&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This is an order of magnitude different expect for &lt;code&gt;tsc&lt;/code&gt; that seems to yield the same results whether it generates declaration files or not.&lt;/p&gt;
&lt;p&gt;There is no obvious winner between &lt;code&gt;swc&lt;/code&gt;, &lt;code&gt;esbuild&lt;/code&gt; and &lt;code&gt;tsup&lt;/code&gt;, but we can see that &lt;code&gt;tsc&lt;/code&gt; is constantly outperformed.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;One sad realization that I had while putting up together this benchmark is that &lt;strong&gt;no matter how fast the compiler is, it&#39;s always going to be at least as slow as &lt;code&gt;tsc --emitDeclarationOnly&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;My personal benchmark isn&#39;t really significant when it comes to performances comparisons... But we can clearly identify that &lt;code&gt;tsc&lt;/code&gt; is the loser!&lt;/p&gt;
&lt;p&gt;Now, with its built-in support for declaration files generation and multiple targets in my opinion &lt;strong&gt;&lt;code&gt;tsup&lt;/code&gt; is the winner! It is tailored for building libraries!&lt;/strong&gt;&lt;br /&gt;
Having only a single command to write to compile our libraries means it easier for maintenance and if, in the future, &lt;code&gt;tsup&lt;/code&gt; figure out a way to generate &lt;code&gt;d.ts&lt;/code&gt; files faster we will benefit from it by upgrading our local version.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Inspiring from React&#39;s useEffect to design effective APIs: the cleanup function pattern</title>
    <link href="https://blog.atomrc.dev/p/cleanup-function-pattern/"/>
    
    <updated>2022-12-27T00:00:00Z</updated>
    
    <published>2022-12-24T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/cleanup-function-pattern/</id>
    <content type="html">&lt;p&gt;React&#39;s &lt;code&gt;useEffect&lt;/code&gt; forces you to implement a quite powerful pattern: the &lt;strong&gt;cleanup function pattern&lt;/strong&gt; (or teardown function pattern).&lt;/p&gt;
&lt;p&gt;Let&#39;s see how we could leverage this pattern to provide &lt;strong&gt;perfect encapsulation&lt;/strong&gt; and make &lt;strong&gt;deceptive calls impossible&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-cleanup-function-pattern&quot; tabindex=&quot;-1&quot;&gt;The cleanup function pattern&lt;/h2&gt;
&lt;p&gt;The idea is quite simple: A function that triggers a long-lived side effect returns another function to teardown this effect.&lt;/p&gt;
&lt;p&gt;The pattern goes as follows:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;effect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// trigger some long lived effect (listening to a websocket, registering DOM event listeners...)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cleanupEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// cleanup the long lived effect&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;React developers will immediately recognize the &lt;a href=&quot;https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1&quot;&gt;&lt;code&gt;useEffect&lt;/code&gt;&lt;/a&gt; pattern.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// trigger some long lived effect&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// cleanup&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This pattern is not so fancy nor new! It has been around in Reactive Programming libraries for a little while. RxJS&#39; &lt;a href=&quot;https://rxjs.dev/guide/subscription&quot;&gt;&lt;code&gt;subscribe&lt;/code&gt; method&lt;/a&gt; follows this pattern, for example.&lt;br /&gt;
The main difference between React and RxJS (or others), is that &lt;strong&gt;RxJS implements the cleanup function pattern&lt;/strong&gt; while &lt;strong&gt;React requires you to implement the pattern&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;benefits-of-the-cleanup-function-pattern&quot; tabindex=&quot;-1&quot;&gt;Benefits of the cleanup function pattern&lt;/h2&gt;
&lt;p&gt;There are two main takeaways to this pattern:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it brings &lt;strong&gt;perfect encapsulation&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;it makes &lt;strong&gt;deceptive calls impossible&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&#39;s take a very common API that could benefit from the cleanup function pattern: the famous &lt;code&gt;(add|remove)EventListener&lt;/code&gt; DOM API.&lt;/p&gt;
&lt;p&gt;A traditional usage of this API would look something like this:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;sendPayload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/*...*/&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; button &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;the-button&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

button&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sendPayload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ... later on&lt;/span&gt;
button&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;removeEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sendPayload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How about we try to implement our own &lt;code&gt;addListener&lt;/code&gt; function that implements the cleanup function pattern?&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;element&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; callback&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;removeEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; callback&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;perfect-encapsulation&quot; tabindex=&quot;-1&quot;&gt;Perfect encapsulation&lt;/h3&gt;
&lt;p&gt;One of the problems of the &lt;code&gt;button.addEventListener&lt;/code&gt; is that you &lt;strong&gt;need to keep track&lt;/strong&gt; of the DOM element (&lt;code&gt;button&lt;/code&gt;), the event name (&lt;code&gt;click&lt;/code&gt;) and the callback (&lt;code&gt;sendPayload&lt;/code&gt;) in order to be able to remove this listener.&lt;br /&gt;
Lose one of those ingredients, and your &lt;code&gt;click&lt;/code&gt; listener is here to stay!&lt;/p&gt;
&lt;p&gt;Thanks to our custom &lt;code&gt;addListener&lt;/code&gt; function that we implemented earlier, a &lt;strong&gt;single reference&lt;/strong&gt; is needed in order to remove the listener:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;sendPayload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/*...*/&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; button &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;the-button&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; removeListener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;button&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sendPayload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    ^ removeListener is the only reference we need to keep&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;removeListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, the references to the button, the event name and the callback are &lt;strong&gt;encapsulated in the cleanup function&lt;/strong&gt;. The only thing we need to keep track of is the &lt;code&gt;removeListener&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;So we could even inline everything&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; removeListener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;the-button&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;em&gt;I &lt;strong&gt;would not&lt;/strong&gt; suggest inlining code like the previous code sample. This example is there just to highlight that it is possible.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;preventing-deceptive-calls&quot; tabindex=&quot;-1&quot;&gt;Preventing deceptive calls&lt;/h3&gt;
&lt;p&gt;Let&#39;s consider the following samples:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;sendPayload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

button&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;removeEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sendPayload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ❌ Useless call, the listener has not been added yet (temporal coupling)&lt;/span&gt;

button&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sendPayload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

button&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;removeEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sendPayload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ❌ The listener is not removed because the reference to the function has changed&lt;/span&gt;

button&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;removeEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;auxclick&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sendPayload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ❌ this is useless since we never added a `auxclick` listener&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some of those calls are not only useless, they are deceptive. You could &lt;em&gt;feel like you have removed the listener&lt;/em&gt;, but in fact it&#39;s still there and active.&lt;/p&gt;
&lt;p&gt;Those calls are made impossible with the cleanup function pattern!&lt;/p&gt;
&lt;p&gt;If you do not have the reference to the &lt;code&gt;cleanupFunction&lt;/code&gt; that you first created by triggering the effect, there is nothing you can do!&lt;br /&gt;
We are preventing what is called a &lt;a href=&quot;https://betterprogramming.pub/temporal-coupling-in-code-e74899f7a48f&quot;&gt;temporal coupling&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;a-concrete-example%3A-listening-to-a-websocket&quot; tabindex=&quot;-1&quot;&gt;A concrete example: Listening to a WebSocket&lt;/h2&gt;
&lt;p&gt;Let&#39;s implement a naive module that subscribes to WebSocket events and forwards them to the consumer:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; ws&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;onEvent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  ws &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WebSocket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;wss://example.com&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  ws&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onmessage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; onEvent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ws&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    ws&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ws &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A few things to note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;close&lt;/code&gt; function can be called even if the connection is not active;&lt;/li&gt;
&lt;li&gt;the module needs to be stateful and keep track of &lt;code&gt;ws&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;we need to perform some checks before we can safely close (&lt;code&gt;if (ws)&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;if we call &lt;code&gt;listen&lt;/code&gt; multiple times there will be instances that cannot be killed anymore, the reference to &lt;code&gt;ws&lt;/code&gt; is lost forever.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, with our newly discovered pattern&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;onEvent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ws &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WebSocket&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;wss://example.com&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  ws&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onmessage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; onEvent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    ws&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the added benefit that the code is now more concise, everything is isolated, this module doesn&#39;t need to keep a local state, and you just cannot &lt;code&gt;close&lt;/code&gt; until you have actually opened the connection.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Next time you are dealing with a long-lived effect, try to play with the idea of returning the function that will kill the effect, and see how it works for you.&lt;/p&gt;
&lt;p&gt;I lately implemented it for &lt;a href=&quot;https://github.com/wireapp/wire-web-packages/blob/eebabf50943170b87f1c8aa6d8cbf4527e9a9238/packages/core/src/Account.ts#L677-L681&quot;&gt;Wire&#39;s webapp connection to the WebSocket&lt;/a&gt;, and I am totally sold 🚀&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>flatMap: an alternative to filter + map</title>
    <link href="https://blog.atomrc.dev/p/flatmap-a-better-filter-map/"/>
    
    <updated>2022-12-14T00:00:00Z</updated>
    
    <published>2022-12-10T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/flatmap-a-better-filter-map/</id>
    <content type="html">&lt;p&gt;Filtering out &lt;code&gt;falsy&lt;/code&gt; values or making sure we are dealing with the correct type before mapping are very common scenarios in webapps.&lt;br /&gt;
We often tend to use &lt;code&gt;filter(...).map(...)&lt;/code&gt; to cover those use-cases.&lt;/p&gt;
&lt;p&gt;But if we breakdown the type signature of a &lt;code&gt;filter + map&lt;/code&gt; operation, we come to realize that there is an operator that is tailored for this: &lt;code&gt;flatMap&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I&#39;m going to use the notation &lt;code&gt;A[n]&lt;/code&gt; to specify the signature of an array of size &lt;code&gt;n&lt;/code&gt; of elements of type &lt;code&gt;A&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;the-filter-%2B-map&#39;s-signature&quot; tabindex=&quot;-1&quot;&gt;The &lt;code&gt;filter + map&lt;/code&gt;&#39;s signature&lt;/h2&gt;
&lt;p&gt;When analyzing the resulting type of a &lt;code&gt;filter + map&lt;/code&gt; call, we find this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;filter&lt;/code&gt;: &lt;code&gt;A[n] =&amp;gt; A&#39;[m]&lt;/code&gt; (where &lt;code&gt;A&#39;&lt;/code&gt; is a subset of &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;m &amp;lt;= n&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;map&lt;/code&gt;: &lt;code&gt;A&#39;[m] =&amp;gt; B[m]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So chained together, a &lt;code&gt;filter + map&lt;/code&gt; has this signature: &lt;code&gt;A[n] =&amp;gt; B[m]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;...Which is exactly what the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap&quot;&gt;&lt;code&gt;flatMap&lt;/code&gt;&lt;/a&gt; operator is about: changing an array in both &lt;strong&gt;type and size&lt;/strong&gt;!&lt;/p&gt;
&lt;h2 id=&quot;filter-mapping-an-array-in-a-single-operation&quot; tabindex=&quot;-1&quot;&gt;Filter-mapping an array in a single operation&lt;/h2&gt;
&lt;p&gt;How about we try to avoid this intermediate step and go straight from &lt;code&gt;A[n]&lt;/code&gt; to our desired &lt;code&gt;B[m]&lt;/code&gt; array?&lt;/p&gt;
&lt;p&gt;Consider the following example:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elements &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; strings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; elements &lt;span class=&quot;token comment&quot;&gt;//               (null|number)[5]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//            number[3]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;16&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// string[3]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ultimately, here, we want to transform an array of 5 &lt;code&gt;null|number&lt;/code&gt; into an array of 3 &lt;code&gt;string&lt;/code&gt;. We want to change both the number of items &lt;strong&gt;and&lt;/strong&gt; the types of the items.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;flatMap&lt;/code&gt; we can achieve the same in a single run&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; strings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; elements&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;item &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;16&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;better-typescript-inference&quot; tabindex=&quot;-1&quot;&gt;Better TypeScript inference&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;filter&lt;/code&gt; has a rather &lt;strong&gt;poor TypeScript integration when it comes to changing types&lt;/strong&gt; (see this GitHub issue: &lt;a href=&quot;https://github.com/microsoft/TypeScript/issues/7657&quot;&gt;Type guards in Array.prototype.filter&lt;/a&gt;). Filtering an array that contains &lt;code&gt;A|B|...&lt;/code&gt; to an array that only contains a subset of those types &lt;strong&gt;does not benefit from any type inference&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;One very common occurrence of this is to filter out &lt;code&gt;falsy&lt;/code&gt; values (&lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt; ...) from an array.&lt;/p&gt;
&lt;p&gt;In this case, you need to write a &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards&quot;&gt;user-defined type guard&lt;/a&gt; in order to have TypeScript understanding the type of your resulting array.&lt;/p&gt;
&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; array &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;three&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;four&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    ^ (string|number)[]&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; numbers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; item &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    ^ (string|number)[] ❌&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; numbers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; item &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; item &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;string&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    ^ string[] ✅&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;User-defined type guards are pretty nice, but they have a &lt;strong&gt;major flaw: they are user-defined&lt;/strong&gt;. Meaning, you can actually lie to TypeScript.
For example, this is valid TypeScript 🙃:&lt;/p&gt;
&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arg&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; arg &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; arg &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the same filtering with &lt;code&gt;flatMap&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; numbers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; item &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;string&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    ^ string[] ✅&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here the TypeScript inference system kicks in and automatically detects the type of your resulting array.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Lately, I got used to replacing all my &lt;code&gt;filter + map&lt;/code&gt; with &lt;code&gt;flatMap&lt;/code&gt;. My code tend to be a bit &lt;strong&gt;more concise&lt;/strong&gt;, but the main takeaway is the &lt;strong&gt;automatic type inference&lt;/strong&gt;.
There is a &lt;a href=&quot;https://www.measurethat.net/Benchmarks/Show/11827/0/flatmap-vs-filtermap&quot;&gt;minor performance boost with &lt;code&gt;flatMap&lt;/code&gt;&lt;/a&gt;, but not significant enough to make it a solid argument, in my opinion.&lt;/p&gt;
&lt;p&gt;One could argue that &lt;code&gt;flatMap&lt;/code&gt; is harder to understand. I believe that it&#39;s just a matter of getting used to it.&lt;/p&gt;
&lt;p&gt;In the end, choosing &lt;code&gt;flatMap&lt;/code&gt; over &lt;code&gt;filter + map&lt;/code&gt; boils down to personal preferences (and agreement with your team). As long as you maintain consistent convention, it is all fine!&lt;/p&gt;
&lt;p&gt;So give a try to &lt;code&gt;flatMap&lt;/code&gt; and see for yourself how you feel about it 🙂&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Recovering lost commits with git reflog</title>
    <link href="https://blog.atomrc.dev/p/git-reflog/"/>
    
    <updated>2022-12-04T00:00:00Z</updated>
    
    <published>2022-12-04T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/git-reflog/</id>
    <content type="html">&lt;p&gt;Once familiar with &lt;code&gt;git&lt;/code&gt;, editing code becomes a breeze. Refactorings and deletions feel as natural and safe as adding code. &lt;code&gt;git&lt;/code&gt; is always there to back us up if something goes awfully wrong!&lt;/p&gt;
&lt;p&gt;But what about &lt;strong&gt;editing the git history itself?&lt;/strong&gt;&lt;br /&gt;
Could someone also have our back when we run &lt;code&gt;rebase&lt;/code&gt; or &lt;code&gt;reset&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;The answer is &amp;quot;yes&amp;quot;! &lt;code&gt;git&lt;/code&gt; has just the right for this job: the &lt;code&gt;reflog&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;Once you have built your own mental model of &lt;code&gt;reflog&lt;/code&gt;, history-modifying commands become as natural and safe as editing code.&lt;/p&gt;
&lt;p&gt;Before we actually dive in into what &lt;code&gt;reflog&lt;/code&gt; is, we need to understand a key concept in &lt;code&gt;git&lt;/code&gt;: the &lt;code&gt;HEAD&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;what-is-head%3F&quot; tabindex=&quot;-1&quot;&gt;What is &lt;code&gt;HEAD&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;HEAD&lt;/code&gt; in &lt;code&gt;git&lt;/code&gt; is a simple pointer of the commit that is currently checked out in your local work tree.&lt;/p&gt;
&lt;p&gt;When digging a little further into the core of git, you realize that &lt;strong&gt;pretty much anything is a reference to a commit in git&lt;/strong&gt;.
&lt;code&gt;branches&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt;, &lt;code&gt;stash&lt;/code&gt; are all commit references.&lt;/p&gt;
&lt;p&gt;A look into the &lt;code&gt;.git/refs&lt;/code&gt; folder will reveal all those references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.git/refs/heads/&amp;lt;branchname&amp;gt;&lt;/code&gt; → points to the latest commit of the branch &lt;code&gt;&amp;lt;branchname&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.git/refs/stash&lt;/code&gt; → points to the latest commit on the &lt;code&gt;stash&lt;/code&gt; (yes, the changes you stash are commits under the hood)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.git/refs/tags/&amp;lt;tagname&amp;gt;&lt;/code&gt; → points to the commit referenced by the tag &lt;code&gt;&amp;lt;tagname&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Along with it, you will find 2 more special commit references in the &lt;code&gt;.git/&lt;/code&gt; folder&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.git/HEAD&lt;/code&gt; → the reference of the commit that is currently checked out in your local repository&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.git/ORIG_HEAD&lt;/code&gt; → the reference of the previous position of the HEAD (somewhat deprecated, &lt;code&gt;reflog&lt;/code&gt; achieves the same goal and much more)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-is-the-reflog%3F&quot; tabindex=&quot;-1&quot;&gt;What is the &lt;code&gt;reflog&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;reflog&lt;/code&gt; is a quite simple concept, actually! It is a &lt;strong&gt;log of all the moves the git &lt;code&gt;HEAD&lt;/code&gt; has ever made&lt;/strong&gt; in your local repository.&lt;/p&gt;
&lt;p&gt;As such, &lt;code&gt;reflog&lt;/code&gt; is a very personal log that will never be shared with the remote repository. You will share the same commit history with your coworkers (modulus the commits that are not pushed) but your &lt;code&gt;reflog&lt;/code&gt; is &lt;em&gt;yours only&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;which-commands-are-moving-the-head%3F&quot; tabindex=&quot;-1&quot;&gt;Which commands are moving the &lt;code&gt;HEAD&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;The rule of thumb is: if you move from one commit to another, then the &lt;code&gt;HEAD&lt;/code&gt; is changing and a new entry is appended to the &lt;code&gt;reflog&lt;/code&gt;.&lt;br /&gt;
To be slightly more exhaustive, let&#39;s explain a few git commands with regard to what it does to the &lt;code&gt;HEAD&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git commit&lt;/code&gt; → creates a new commit and moves the &lt;code&gt;HEAD&lt;/code&gt; to this commit&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout &amp;lt;branch&amp;gt;&lt;/code&gt; → moves the &lt;code&gt;HEAD&lt;/code&gt; from its current commit to the commit referenced by &lt;code&gt;&amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull&lt;/code&gt; → pulls the missing commits from the remote and moves the &lt;code&gt;HEAD&lt;/code&gt; to the latest commit&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git merge&lt;/code&gt; → creates a merge commit and moves &lt;code&gt;HEAD&lt;/code&gt; to point to this merge commit&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git reset HEAD~1&lt;/code&gt; → moves the &lt;code&gt;HEAD&lt;/code&gt; to the previous commit&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Every single of those moves will be inserted into the &lt;code&gt;reflog&lt;/code&gt;.&lt;/p&gt;
&lt;figure&gt;
  &lt;video controls=&quot;&quot; alt=&quot;git reflog in action&quot;&gt;
    &lt;source src=&quot;https://i.imgur.com/sPAWe6v.mp4&quot; type=&quot;video/mp4&quot; /&gt;
  &lt;/video&gt;
  &lt;figcaption&gt;On the left, you see some git commands being executed. On the right is the live &lt;code&gt;reflog&lt;/code&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Let&#39;s take a simple example in order to let the concept sink in.&lt;br /&gt;
Imagine you are on branch &lt;code&gt;feature&lt;/code&gt; and this is the initial state of the history:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A initial commit &amp;lt; &lt;i&gt;(HEAD, feature)&lt;/i&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s run a bunch of &lt;code&gt;git&lt;/code&gt; commands on top of it&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git commit -m &#39;second commit&#39;&lt;/code&gt;: moves &lt;code&gt;HEAD&lt;/code&gt; and &lt;code&gt;feature&lt;/code&gt; to the newly created commit&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;B second commit &amp;lt; &lt;i&gt;(HEAD, feature)&lt;/i&gt;
|
A initial commit&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;git checkout A&lt;/code&gt;: moves &lt;code&gt;HEAD&lt;/code&gt; to commit &lt;code&gt;A&lt;/code&gt; (but &lt;code&gt;feature&lt;/code&gt; is still pointing to &lt;code&gt;B&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;B second commit &amp;lt; &lt;i&gt;(feature)&lt;/i&gt;
|
A initial commit &amp;lt; &lt;i&gt;(HEAD)&lt;/i&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;git checkout feature&lt;/code&gt;: moves &lt;code&gt;HEAD&lt;/code&gt; back to the commit referenced by &lt;code&gt;feature&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;B second commit &amp;lt; &lt;i&gt;(HEAD, feature)&lt;/i&gt;
|
A initial commit&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;git reset A&lt;/code&gt;: moves both &lt;code&gt;HEAD&lt;/code&gt; and &lt;code&gt;feature&lt;/code&gt; to commit &lt;code&gt;A&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;B second commit
|
A initial commit &amp;lt; &lt;i&gt;(HEAD, feature)&lt;/i&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every single of those moves will be recorded in the &lt;code&gt;reflog&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;real-life-example%3A-recovering-from-a-reset&quot; tabindex=&quot;-1&quot;&gt;Real life example: recovering from a &lt;code&gt;reset&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s say you ran the examples commands that we saw earlier. You are in that state&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;B
|
A &amp;lt; &lt;i&gt;(HEAD, feature)&lt;/i&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both &lt;code&gt;HEAD&lt;/code&gt; and &lt;code&gt;feature&lt;/code&gt; are pointing to &lt;code&gt;A&lt;/code&gt; and you might feel that commit &lt;code&gt;B&lt;/code&gt; is lost forever.&lt;/p&gt;
&lt;p&gt;Fear not, commit &lt;code&gt;B&lt;/code&gt; is all but lost. It has just become &lt;strong&gt;unreachable&lt;/strong&gt; from the branches you have... But it still exists in &lt;code&gt;git&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;Unfortunately, commit hashes usually do not look like &lt;code&gt;A&lt;/code&gt; but more something like &lt;code&gt;f1fec78c3a05708d7cb55d9e213f1ac51292b52f&lt;/code&gt;.  
This makes it impossible, for a human at least, to just recall that hash and run &lt;code&gt;git reset &amp;lt;commithash&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That&#39;s where the &lt;code&gt;reflog&lt;/code&gt; comes into play.&lt;/p&gt;
&lt;p&gt;As we said earlier, every single move you make between commits is recorded in the &lt;code&gt;reflog&lt;/code&gt;.  
So, let&#39;s have a look at that &lt;code&gt;reflog&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A HEAD@{0}: reset: moving to A
B HEAD@{1}: checkout: moving from A to feature
A HEAD@{2}: checkout: moving from feature to A
B HEAD@{3}: commit: second commit&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The entire story of what happened in the previous example is just lying there. We can see everything we did in reverse chronology order (the most recent moves on the top). We can reconstruct the story just by reading this log from bottom to top.  
Most importantly, we now have the commit hash that we are interested in recovering: &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So we have a few options to recover our commit:&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; reset B &lt;span class=&quot;token comment&quot;&gt;# reseting our current branch to the commit hash we want&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; reset HEAD@&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# reset our current branch to the previous state of `HEAD`&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cherry-pick B &lt;span class=&quot;token comment&quot;&gt;# create a new commit on top of `feature` with the content of commit `B`&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# last option is only if there is a single commit you want to recover&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Recovering from a failed &lt;code&gt;rebase&lt;/code&gt; is pretty much similar.&lt;br /&gt;
It is just a matter of finding the previous top commit of the branch in the &lt;code&gt;reflog&lt;/code&gt; and running &lt;code&gt;git reset &amp;lt;previous-top-commit-hash&amp;gt;&lt;/code&gt;. You will find all the initial commits &lt;strong&gt;exactly as they were before the rebase was initiated&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;One thing you can keep in mind is: &lt;strong&gt;There are no lost commits in git, only harder-to-reach ones!&lt;/strong&gt;
Once something is committed to &lt;code&gt;git&lt;/code&gt;, it is here to stay! A hard-to-reach commit is just a &lt;code&gt;git reflog&lt;/code&gt; away!&lt;/p&gt;
&lt;p&gt;So, do not fear playing with &lt;code&gt;reset&lt;/code&gt; or &lt;code&gt;rebase&lt;/code&gt; in your feature branches and enjoy confident history rewritings* 🤓! &lt;strong&gt;Git is here to back you up!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;*But please in mind that rewriting history of branches shared with coworkers is never a good idea ;)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Get to know your browser&#39;s performance profiler</title>
    <link href="https://blog.atomrc.dev/p/js-performance-profiling/"/>
    
    <updated>2022-05-05T00:00:00Z</updated>
    
    <published>2022-05-05T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/js-performance-profiling/</id>
    <content type="html">&lt;p&gt;At some point in your career, you might have glanced over the &lt;code&gt;Performance&lt;/code&gt; tab in the devtools of your favorite browser. You eventually tried to generate a profile but probably got quickly discouraged by it. The high density of information displayed makes it a little overwhelming and somewhat scary.
I have been there, I feel you!&lt;/p&gt;
&lt;p&gt;Good news is: the learning curve is not actually that steep!!&lt;br /&gt;
Once you have grasped a few concepts it suddenly becomes your most valued tool to tackle performance bottlenecks.&lt;/p&gt;
&lt;p&gt;This article will give you a few keys to understand how the profiler works and how to make a good use of it.&lt;br /&gt;
Let&#39;s completely forget about &lt;code&gt;console.log&lt;/code&gt; and &lt;code&gt;console.time&lt;/code&gt;, today we are diving into the &lt;code&gt;Performance Profiler&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Side note&lt;/em&gt;: I won&#39;t go too deep into complex scenarios here but I will eventually do a follow up article about advanced techniques.&lt;/p&gt;
&lt;h2 id=&quot;the-data-model&quot; tabindex=&quot;-1&quot;&gt;The data model&lt;/h2&gt;
&lt;p&gt;The first step that I took to actually understand how the profiler works was to read the &lt;a href=&quot;https://profiler.firefox.com/docs/#/&quot;&gt;Mozilla documentation about their new performance profiler&lt;/a&gt; (This is an excellent doc, go read it).&lt;/p&gt;
&lt;p&gt;The first &lt;em&gt;waouh&lt;/em&gt; effect that I had was when I got to see the data model that the profiler was using. It&#39;s actually pretty simple&lt;/p&gt;
&lt;p&gt;In Mozilla&#39;s documentation, the data model is represented this way:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A A A
| | |
v v v
B B B
  |
  v
  C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt; are function names and on the &lt;code&gt;X&lt;/code&gt; axis we get time.
By default Firefox and Chrome&#39;s profiler is configured to take a snapshot every 1ms, which means that here every column represents 1ms.&lt;/p&gt;
&lt;p&gt;In this example that means that the stack has evolved like this over time&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;at 0ms &lt;code&gt;A&lt;/code&gt; was calling &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; was still running&lt;/li&gt;
&lt;li&gt;at 1ms &lt;code&gt;B&lt;/code&gt; was calling &lt;code&gt;C&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt; was still running&lt;/li&gt;
&lt;li&gt;at 2ms &lt;code&gt;C&lt;/code&gt; had finished its work and we are back in &lt;code&gt;B&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;at 3ms the stack was empty&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What the profiler can deduce from this is that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt; almost instantly called &lt;code&gt;B&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;We stayed ~1ms in &lt;code&gt;B&lt;/code&gt; before calling &lt;code&gt;C&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C&lt;/code&gt; took ~1ms to execute;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;B&lt;/code&gt; took again ~1 more ms after calling &lt;code&gt;C&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt; ended right after calling &lt;code&gt;B&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;with this model in mind, we can create some profile data&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A A A A A A A A A
| | | | | | | | |
V V V V V V V V V
B B B B B B B B B
              |
              V
              C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;B&lt;/code&gt; is taking a bit of time before and after calling &lt;code&gt;C&lt;/code&gt;. We spent ~1ms in &lt;code&gt;C&lt;/code&gt; and no time in &lt;code&gt;A&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A A A A A A A A A
              | |
              V V
              B B
              |
              V
              C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;A&lt;/code&gt; is taking a bit of time before calling &lt;code&gt;B&lt;/code&gt;. &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt; are taking ~1ms&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-limits-of-this-model&quot; tabindex=&quot;-1&quot;&gt;The limits of this model&lt;/h2&gt;
&lt;p&gt;Since the profiler is only taking 1 sample/ms, it means that a function call that takes less that 1ms has a high chance of not showing up in the generated profile.&lt;/p&gt;
&lt;p&gt;Let&#39;s imagine the following scenario&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt; takes 0.5ms // snapshot #1&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt; takes 0.4ms&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt; takes 0.2ms // snapshot #2&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;E&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt; takes 0.5ms&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generated profile will, most likely, look something like this&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A A
| |
v v
B D&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There will be no mention of &lt;code&gt;C&lt;/code&gt; or &lt;code&gt;E&lt;/code&gt; in this profile.&lt;/p&gt;
&lt;p&gt;But, well, we are here to debug long tasks, remember? No need to have those fast executing functions in there. We do not care about them!&lt;/p&gt;
&lt;h2 id=&quot;self-time-vs-total-time&quot; tabindex=&quot;-1&quot;&gt;self time vs total time&lt;/h2&gt;
&lt;p&gt;One slightly confusing notion in the profiler is the &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;total&lt;/code&gt; time.&lt;br /&gt;
It&#39;s actually a notion that can be quite easily understood, though.&lt;/p&gt;
&lt;p&gt;They can be defined this way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;self&lt;/code&gt; is the time spent in the function itself&lt;/li&gt;
&lt;li&gt;&lt;code&gt;total&lt;/code&gt; is the time spent in the function and all the children functions that it calls&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get a feeling for it, here is a concrete example:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;superExpensive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1e10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;superExpensiveComputation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt; takes 1000ms&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1e6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ^ takes 5ms&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;main&lt;/code&gt; will have a self time of &lt;code&gt;5ms&lt;/code&gt; but a &lt;code&gt;total&lt;/code&gt; time of &lt;code&gt;1005ms&lt;/code&gt;.&lt;br /&gt;
&lt;code&gt;superExpensiveComputation&lt;/code&gt; will have a &lt;code&gt;total&lt;/code&gt; and &lt;code&gt;self&lt;/code&gt; time of &lt;code&gt;1000ms&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;total&lt;/code&gt; time helps identify parts of the code that are problematic while &lt;code&gt;self&lt;/code&gt; time allows you to narrow down your search to the function that actually requires your attention.&lt;/p&gt;
&lt;h2 id=&quot;diving-into-the-ui&quot; tabindex=&quot;-1&quot;&gt;Diving into the UI&lt;/h2&gt;
&lt;p&gt;With this model in mind, the UI starts making sense. The notions we have seen earlier start to be useful to make good use of the UI.&lt;br /&gt;
I am going to focus on the Firefox&#39;s profiler here but the same concepts apply to Chrome&#39;s profiler as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Side note&lt;/strong&gt; This is an interactive article. When you see a &lt;code&gt;Try me&lt;/code&gt; button on the page, feel free to open your &lt;code&gt;Performance&lt;/code&gt; tab, start recording and click the button so you can play around with the generated profile. Note that depending on the computer you use it might freeze your browser a bit or be too fast to actually show up in the profile...&lt;/p&gt;
&lt;h3 id=&quot;identify-long-top-level-functions%3A-the-call-tree&quot; tabindex=&quot;-1&quot;&gt;Identify long top-level functions: The call tree&lt;/h3&gt;
&lt;p&gt;Let&#39;s take a super simple code sample to get started.
Imagine there is a button somewhere and when clicking on it, we trigger the function &lt;code&gt;computeNumber&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generateNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;nbIterations&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; nbIterations&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    number &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; number&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;computeNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;generateNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1e9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;button onclick=&quot;computeNumber()&quot;&gt;Try me&lt;/button&gt;&lt;/p&gt;
&lt;script&gt;
function generateNumber(nbIterations) {
  let number = 0;
  for (let i = 0; i &lt; nbIterations; i++) {
    number += Math.random();
  }
  return number;
}

function computeNumber() {
  console.log(generateNumber(1e9));
}
&lt;/script&gt;
&lt;p&gt;This is what we will get in our profiler report:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://blog.atomrc.dev/img/Dc5ueUg5ol-300.avif 300w, https://blog.atomrc.dev/img/Dc5ueUg5ol-600.avif 600w, https://blog.atomrc.dev/img/Dc5ueUg5ol-900.avif 900w&quot; sizes=&quot;(max-width:300px) 300px, (max-width:600px) 600px, 900px&quot; /&gt;&lt;source type=&quot;image/jpeg&quot; srcset=&quot;https://blog.atomrc.dev/img/Dc5ueUg5ol-300.jpeg 300w, https://blog.atomrc.dev/img/Dc5ueUg5ol-600.jpeg 600w, https://blog.atomrc.dev/img/Dc5ueUg5ol-900.jpeg 900w&quot; sizes=&quot;(max-width:300px) 300px, (max-width:600px) 600px, 900px&quot; /&gt;&lt;img alt=&quot;Screenshot of the Firefox&#39;s profiler report&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://blog.atomrc.dev/img/Dc5ueUg5ol-300.jpeg&quot; width=&quot;900&quot; height=&quot;672&quot; /&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;[1]&lt;/em&gt; Since the profiler is actually profiling all the Firefox&#39;s processes, we want to make sure we are just inspecting the current web app we are working on&lt;/li&gt;
&lt;li&gt;&lt;em&gt;[2]&lt;/em&gt; We are web developer here, no need for the browser&#39;s internal stack traces, let&#39;s only keep JS stack traces&lt;/li&gt;
&lt;li&gt;&lt;em&gt;[3]&lt;/em&gt; We clearly see that we are spending the most amount of time in the &lt;code&gt;generateNumber&lt;/code&gt; function (here the function has appeared in 488 samples, which means it has run for, at least, 488ms)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The call tree will allow you to quickly identify which top level functions are taking time. It&#39;s a good overview of where to start digging, but it does not help you quickly identify nested functions that have a long &lt;code&gt;self&lt;/code&gt; time.&lt;/p&gt;
&lt;h3 id=&quot;identify-long-nested-functions%3A-inverting-the-call-stack&quot; tabindex=&quot;-1&quot;&gt;Identify long nested functions: Inverting the call stack&lt;/h3&gt;
&lt;p&gt;Now, let&#39;s consider the following&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;computeMultipleNumbers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fnName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// We create a function with a random name&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;function &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;fnName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;() {
        return generateNumber(1e7);
      } return &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;fnName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    number &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;button onclick=&quot;computeMultipleNumbers()&quot;&gt;Try me&lt;/button&gt;&lt;/p&gt;
&lt;script&gt;
function computeMultipleNumbers() {
  let number = 0;
  for (let i = 0; i &lt; 10; i++) {
    const fnName = `gen${Math.round(Math.random() * 100)}`;
    // We create a function with a random name
    const fn = new Function(`function ${fnName}() {
        return generateNumber(1e7);
      } return ${fnName}`);
    number += fn()();
  }
  console.log(number)
}
&lt;/script&gt;
&lt;p&gt;The particularity of this function is that it generates named functions with random names. Which means that now &lt;code&gt;generateNumber&lt;/code&gt; will be called from many different functions.&lt;/p&gt;
&lt;p&gt;Let&#39;s see what the profile looks like&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://blog.atomrc.dev/img/7di8aGk7lU-300.avif 300w, https://blog.atomrc.dev/img/7di8aGk7lU-600.avif 600w&quot; sizes=&quot;(max-width:300px) 300px, (max-width:600px) 600px, 900px&quot; /&gt;&lt;source type=&quot;image/jpeg&quot; srcset=&quot;https://blog.atomrc.dev/img/7di8aGk7lU-300.jpeg 300w, https://blog.atomrc.dev/img/7di8aGk7lU-600.jpeg 600w&quot; sizes=&quot;(max-width:300px) 300px, (max-width:600px) 600px, 900px&quot; /&gt;&lt;img alt=&quot;Firefox&#39;s profile screenshot for a function that calls multiple sub-functions&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://blog.atomrc.dev/img/7di8aGk7lU-300.jpeg&quot; width=&quot;600&quot; height=&quot;317&quot; /&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;Here we can see that there are many functions called, but they all have an empty &lt;code&gt;self&lt;/code&gt; time. Which means this is not the function where we actually spent time, they were waiting for something else to finish.&lt;/p&gt;
&lt;p&gt;Now, if we invert the stack.&lt;/p&gt;
&lt;video controls=&quot;&quot; autplay=&quot;&quot; loop=&quot;&quot;&gt;
    &lt;source src=&quot;https://i.imgur.com/SNTD2Ph.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;Here it becomes clear where we actually spent time: in the &lt;code&gt;generateNumber&lt;/code&gt; function :)&lt;/p&gt;
&lt;p&gt;The inversion actually sorts the function with the highest &lt;code&gt;self&lt;/code&gt; time and flatten them at the root of the tree. It&#39;s an excellent way to identify a time-consuming function and you get its call stack right next to it. With this you know exactly &lt;strong&gt;which function is a problem and from where it was called&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This call tree&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;topLevel     // self 0
  first      // self 0
  second     // self 0
    third    // self 10
    fourth   // self 7
      fifth  // self 8&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Will give you this inverted call stack&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;third   //self 10
  second
    topLevel
fifth   // self 8
  fourth
    second
      topLevel
fourth  // self 7
  second
    topLevel&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we can quickly identify that we spent ~10ms in &lt;code&gt;third&lt;/code&gt; called from &lt;code&gt;topLevel &amp;gt; second&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this article we have covered the basic functions of the profiler. We have seen how to use the &lt;code&gt;call tree&lt;/code&gt; and &lt;code&gt;inverted call stack&lt;/code&gt; to quickly identify time consuming functions in your application.&lt;/p&gt;
&lt;p&gt;Now those time consuming functions are not necessarily the functions that you need to optimize. The problem could lie on the parent function or even higher in the tree. The &lt;code&gt;inverted call stack&lt;/code&gt; gives you a good starting point to walk your way up the problematic part of your app.&lt;/p&gt;
&lt;p&gt;We have not covered here what the &lt;code&gt;Flame Graph&lt;/code&gt; or &lt;code&gt;Stack Chart&lt;/code&gt; are, how to profile async code or advanced techniques like &lt;code&gt;markers&lt;/code&gt;. This is something I would love to cover in a follow up article. Feel free to ping me on &lt;a href=&quot;https://twitter.com/atomrc&quot;&gt;Twitter&lt;/a&gt; if this would interest you ;)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Why React Hooks cannot be conditioned</title>
    <link href="https://blog.atomrc.dev/p/why-you-cannot-condition-react-hooks/"/>
    
    <updated>2021-05-30T00:00:00Z</updated>
    
    <published>2021-05-30T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/why-you-cannot-condition-react-hooks/</id>
    <content type="html">&lt;p&gt;If you&#39;ve used &lt;a href=&quot;https://reactjs.org/docs/hooks-intro.html&quot;&gt;React hooks&lt;/a&gt; along with the &lt;a href=&quot;https://github.com/facebook/react/tree/master/packages/eslint-plugin-react-hooks&quot;&gt;&lt;code&gt;eslint-plugin-react-hooks&lt;/code&gt;&lt;/a&gt;, you might have encountered the unexpected warning &lt;code&gt;React Hook &amp;quot;useState&amp;quot; is called conditionally.&lt;/code&gt;.&lt;br /&gt;
One can be quite surprised by this warning. At least I was.&lt;/p&gt;
&lt;p&gt;Back then I had already seen a similar pattern with &lt;a href=&quot;https://knockoutjs.com/&quot;&gt;&lt;code&gt;knockoutjs&lt;/code&gt;&lt;/a&gt; and I though it was a pretty bad design flaw. I was puzzled a modern tool, like React, would allow for such a weakness.&lt;/p&gt;
&lt;p&gt;So I decided to investigate and deep dive into how React Hooks work and why they cannot be conditioned.&lt;/p&gt;
&lt;h2 id=&quot;tldr&quot; tabindex=&quot;-1&quot;&gt;TLDR&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;the hook system is a quite big stateful machine that records every call to any hook (&lt;code&gt;useEffect&lt;/code&gt;, &lt;code&gt;useState&lt;/code&gt; ...);&lt;/li&gt;
&lt;li&gt;at component&#39;s mount time &lt;strong&gt;all&lt;/strong&gt; React hooks must be called so that they are registered against the hook system;&lt;/li&gt;
&lt;li&gt;the order at which React hooks are called in a component must be stable through time and renders.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;disclaimer&quot; tabindex=&quot;-1&quot;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;I ran my investigations against React &lt;code&gt;v17&lt;/code&gt;. Other versions might work differently (I am pretty sure it does not).&lt;/p&gt;
&lt;p&gt;Also bear in mind that the code you are going to see in the article is not actual code from the React codebase. It&#39;s my own interpretation of what I read in there. The names of variables and functions have been changed for the sake of simplicity.&lt;/p&gt;
&lt;h2 id=&quot;what-happens-when-a-hook-function-is-called&quot; tabindex=&quot;-1&quot;&gt;What happens when a hook function is called&lt;/h2&gt;
&lt;p&gt;Hook functions (&lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useEffect&lt;/code&gt;, ...) are rather interesting functions in that they are stateful at two levels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They mutate values in a global state;&lt;/li&gt;
&lt;li&gt;Depending when, in the component&#39;s lifecyle, they are called (&lt;code&gt;mount&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, ...) they do not run the same code.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;at-mount-time&quot; tabindex=&quot;-1&quot;&gt;At mount time&lt;/h3&gt;
&lt;p&gt;Let&#39;s take a very simple component as a working example:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setFirst&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;first&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;second&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setSecond&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;second&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/*...*/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When &lt;code&gt;React&lt;/code&gt; mounts this component, it will create a state that is associated with the instance of the component. In this state it will store, among other things, a linked list of all the hooks that have been called during the mounting of the component.&lt;/p&gt;
&lt;p&gt;So when &lt;code&gt;React&lt;/code&gt; executes &lt;code&gt;Component()&lt;/code&gt; any call to a &lt;code&gt;use*&lt;/code&gt; function will create an entry in the linked list and we will end up with a state that looks like this:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;first&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;second&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// End of the linked list&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Around a component initialisation, in React, we have code that looks like this:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// global variable that will be mutated by each and every use* call&lt;/span&gt;
  global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentComponentHooks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// keeps track of the last hook that was mounted&lt;/span&gt;
  global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastMountedHook &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; children &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// [...]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we try to guess the body of the &lt;code&gt;useState&lt;/code&gt; (&lt;code&gt;useEffect&lt;/code&gt; would be, somewhat, similar) it should look something like:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Creates the new entry&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; hook &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentComponentHooks &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// If it is the first entry, stores it in the global object&lt;/span&gt;
    global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentComponentHooks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; hook&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Add the current hook to the `next` property&lt;/span&gt;
    global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastMountedHook&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;next &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; hook&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Keep track that this hook is the last one we mounted&lt;/span&gt;
  global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastMountedHook &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; hook&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// [...]&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updateState&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// finally returns the initial value plus an update function&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the component we had earlier this is what the &lt;code&gt;global.currentComponentHooks&lt;/code&gt; will look like as lines are executed:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// null&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setFirst&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;first&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// {value &#39;first&#39;, next: null}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;second&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setSecond&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;second&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// {value &#39;first&#39;, next: {value: &#39;second&#39;, next: null}}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/*...*/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;at-update-time&quot; tabindex=&quot;-1&quot;&gt;At update time&lt;/h3&gt;
&lt;p&gt;Let&#39;s imagine something happened on the UI level and &lt;code&gt;setFirst(&#39;updated&#39;)&lt;/code&gt; was called.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I am not going to describe how the &lt;code&gt;setFirst&lt;/code&gt; function behaves. Just bear in mind that it is bound to the relevant entry in the linked list and simply mutates the &lt;code&gt;value&lt;/code&gt; property. It then triggers a re-rendering on React&#39;s side.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;At mount time we have stacked our different hooks in a linked list. At update time we are going to traverse our linked list and read each stored value.&lt;/p&gt;
&lt;p&gt;On React&#39;s side we need to create a pointer that will point to the root of our linked list before we re-render our component.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentHook &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentComponentHooks&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// {value &#39;first&#39;, next: {value: &#39;second&#39;, next: null}}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; children &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// global.currentHook === null&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It means that the body of the &lt;code&gt;useState&lt;/code&gt; function must have changed.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* note that we do not need the initial value anymore */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/*value*/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; hook &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentHook&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentHook &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; hook&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;next&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// we move the pointer to the next hook&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// [...]&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;hook&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updateState&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And from our component&#39;s context this is how the &lt;code&gt;currentHook&lt;/code&gt; pointer evolves.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// {value &#39;updated&#39;, next: {value: &#39;second&#39;, next: null}}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setFirst&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;first&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// first === &#39;updated&#39; our mutated state&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// {value &#39;second&#39;, next: null}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;second&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setSecond&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;second&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// second === &#39;second&#39; the unchanged initial state&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/*...*/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;so...-why-can&#39;t-we-condition-a-hook%3F&quot; tabindex=&quot;-1&quot;&gt;So... Why can&#39;t we condition a hook?&lt;/h2&gt;
&lt;p&gt;Now that we have seen the internals of how hooks work, let&#39;s see what would happen if we conditioned one of them.
A (arguably!) valid scenario for conditioning a hook would probably be triggering an &lt;code&gt;effect&lt;/code&gt; depending on some props. (Note that, just like &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useEffect&lt;/code&gt; are also added the the linked list of all the hooks of a component)&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;doEffect&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setFirst&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doEffect&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/*...*/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;second&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setSecond&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let&#39;s say that the component will mount with &lt;code&gt;{doEffect: false}&lt;/code&gt;.
We will end up with that linked list:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{value: 0, next: {value: 0, next: null}}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We only have two elements and the &lt;code&gt;useEffect&lt;/code&gt; does not exist in our list.&lt;/p&gt;
&lt;p&gt;If ever &lt;code&gt;doEffect&lt;/code&gt; switches to &lt;code&gt;true&lt;/code&gt; we will now try to access a hook that was not registered&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; doEffect &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// {value: 0, next: {value: 0, next: null}}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setFirst&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doEffect&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// {value: 0, next: null}&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/*...*/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ⚠️ Wrong hook here&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// null&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;second&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setSecond&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ⚠️ No hook left!!&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to fix this, we just need to move our condition inside the body of the &lt;code&gt;useEffect&lt;/code&gt; hook (and not forget to add it in the dependency of the &lt;code&gt;useEffect&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doEffect&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Do your magic&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;doEffect&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;React Hooks have quite changed how we write React apps. As a React user, I find being able to write only functional components (as opposed to class components) to be very pleasant!&lt;/p&gt;
&lt;p&gt;But this comfort comes at a price:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hooks feel like black magic and make the lifecycle of the component hard to grasp (and actually you should probably &lt;a href=&quot;https://kentcdodds.com/blog/react-hooks-pitfalls#pitfall-3-thinking-in-lifecycles&quot;&gt;not think in lifecycles&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;we need stricts rules regarding how hooks are called.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I would also add that all those states inside the React codebase make the flow pretty hard to follow and understand. I can not thank enough my debugger for the step-by-step execution. Without it, this article would probably not exist 😅!!&lt;/p&gt;
&lt;p&gt;Although the &lt;code&gt;eslint-plugin-react-hooks&lt;/code&gt; is almost always included in any React codebase, needing a special &lt;code&gt;eslint&lt;/code&gt; rule feels like a somewhat serious design flaw. That being said, and in my humble opinion, this is an acceptable tradeoff though :)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Monitoring: A case study for EventTarget</title>
    <link href="https://blog.atomrc.dev/p/case-study-event-target/"/>
    
    <updated>2021-05-05T00:00:00Z</updated>
    
    <published>2021-05-05T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/case-study-event-target/</id>
    <content type="html">&lt;p&gt;If you work for a data-driven company chances are you had to implement a tracker at some point.&lt;br /&gt;
I often see this step being rushed and written straight into the business code.&lt;br /&gt;
A lot of attention is given to having a clean implementation of the feature but little thoughts are given to how the tracking impacts the implementation.&lt;/p&gt;
&lt;p&gt;Lately, at Deezer, I have been working on a feature that allows two devices to send messages to each other.&lt;br /&gt;
I thought this would be a nice opportunity to document my usual approach to monitoring 🧑‍💻&lt;/p&gt;
&lt;p&gt;For this, I set the following contraints:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;not a single mention of the tracking mechanism should appear in the business code;&lt;/li&gt;
&lt;li&gt;deactivating the tracking feature should be a single-line change.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-business-logic&quot; tabindex=&quot;-1&quot;&gt;The business logic&lt;/h2&gt;
&lt;p&gt;We are going to focus on the method that sends a message to the remote peer.
The method sends a message on the connection and waits for the peer to reply with an &lt;code&gt;ack&lt;/code&gt; message before resolving the returned &lt;code&gt;Promise&lt;/code&gt;.&lt;br /&gt;
(&lt;em&gt;The details of how the &lt;code&gt;ack&lt;/code&gt; is matched is hidden in the &lt;code&gt;addAckListener&lt;/code&gt; method for the sake of simplicity.&lt;/em&gt;)&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Connection&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;sendMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; messageId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;peerConnection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;resolve&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addAckListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;messageId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; error &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The metrics we want to monitor are the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the number of successful messages;&lt;/li&gt;
&lt;li&gt;the number of failed messages;&lt;/li&gt;
&lt;li&gt;the time a message needs to do the round trip (between the message being sent and the &lt;code&gt;ack&lt;/code&gt; being received).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;a-naive-implementation&quot; tabindex=&quot;-1&quot;&gt;A naive implementation&lt;/h2&gt;
&lt;p&gt;Before over-engineering anything I find it useful to start-off with a naive implementation.&lt;br /&gt;
It usually helps me clearing up the contraints before extracting them somewhere else.&lt;/p&gt;
&lt;p&gt;The first thing that comes to mind is to add the tracking bits directly into the code that actually sends the message... Let&#39;s go for it 🤓&lt;/p&gt;
&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;class Connection {
&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; // ...
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; sendMessage(message) {
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   const messageId = uuid();
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   this.peerConnection.send({ id: uuid(), message });
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   const timer = Date.now(); // Keep track of the time the message was sent at
&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   return new Promise((resolve, reject) =&gt; {
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     this.addAckListener(messageId, (error?: number) =&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;       const elapsed = Date.now() - timer;
&lt;/span&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;       trackMetrics(&#39;latency&#39;, elapsed);
&lt;/span&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;       if (err) {
&lt;/span&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;         trackMetrics(&#39;message_error&#39;, err);
&lt;/span&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;       } else {
&lt;/span&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;         trackMetrics(&#39;message_success&#39;);
&lt;/span&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;       }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;       return error ? reject(error) : resolve();
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     });
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   });
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is quite a bit of code that pollutes the actual business logic. The responsibility of the &lt;code&gt;sendMessage&lt;/code&gt; has been altered. It cannot be described without an &amp;quot;and&amp;quot; in the sentence: It sends messages &lt;strong&gt;and&lt;/strong&gt; tracks metrics.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;👌 easy to implement (almost a no-brainer)&lt;/li&gt;
&lt;li&gt;👌 factorised (monitoring is implemented once and work for every message sent)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;👎 strong impact on the business logic&lt;/li&gt;
&lt;li&gt;👎 not trivial to deactivate (need to comment or condition many lines with the risk of disabling lines of actual business logic)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;moving-the-tracking-logic-to-the-parent&quot; tabindex=&quot;-1&quot;&gt;Moving the tracking logic to the parent&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;sendMessage&lt;/code&gt; method returns a &lt;code&gt;Promise&lt;/code&gt;. This is definitely something we can use!&lt;/p&gt;
&lt;p&gt;Along with the value it holds, a &lt;code&gt;Promise&lt;/code&gt; also carries around:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the success state of the operation;&lt;/li&gt;
&lt;li&gt;the time the operation took to complete (or to fail).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is exactly the pieces of information we need for our tracker 👌&lt;/p&gt;
&lt;p&gt;Let&#39;s say the consumer does something like this:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;connection
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;play&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/*...*/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;showSuccess&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We could easily plug our tracking mechanism right here:&lt;/p&gt;
&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;const timer = Date.now();
&lt;/span&gt;&lt;/span&gt;connection
&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; .sendMessage({ type: &quot;play&quot; /*...*/ })
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; .then(() =&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   trackMetrics(&#39;message_success&#39;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   showSuccess();
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; })
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; .catch((err) =&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   trackMetrics(&#39;message_error&#39;, err);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   showError(err);
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; })
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; .then(() =&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   const elapsed = Date.now() - timer;
&lt;/span&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   trackMetrics(&#39;latency&#39;, elapsed);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;👌 easy to implement&lt;/li&gt;
&lt;li&gt;👌 non intrusive (the business logic is left untouched)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;👎 unfactorised (every call to &lt;code&gt;sendMessage&lt;/code&gt; need to be modified)&lt;/li&gt;
&lt;li&gt;👎 even harder to disable (need to disable &lt;strong&gt;all&lt;/strong&gt; the placed where &lt;code&gt;sendMessage&lt;/code&gt; is called)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;extracting-the-monitoring-logic-to-a-separate-unit&quot; tabindex=&quot;-1&quot;&gt;Extracting the monitoring logic to a separate unit&lt;/h2&gt;
&lt;p&gt;Our previous version allowed for the pure business logic to be left untouched. This is good. But now it is our view layer that is orchestrating the monitoring.&lt;/p&gt;
&lt;p&gt;Maybe we could try to extract this logic somewhere else.&lt;/p&gt;
&lt;p&gt;Another property of &lt;code&gt;Promise&lt;/code&gt; is that it can be &lt;strong&gt;forked&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It is well known that &lt;code&gt;Promise&lt;/code&gt; can be chained:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doStuff&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doOtherStuff&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But we often forget that it can also be forked:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doStuff&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doOtherStuff&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We could use that property to clean our view layer code.&lt;/p&gt;
&lt;p&gt;This would be our implementation of our monitoring tool:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;trackMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;messagePromise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; timer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  messagePromise
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;trackMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;message_success&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;trackMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;message_failed&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elapsed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; timer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;trackMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;latency&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; elapsed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; messagePromise&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we just plug-in some callback to execute after the promise &lt;code&gt;resolve&lt;/code&gt;/&lt;code&gt;reject&lt;/code&gt; and we return the initial, unmodified, promise.&lt;/p&gt;
&lt;p&gt;The TypesScript signature is the following &lt;code&gt;trackMessage(messagePromise: Promise&amp;lt;Payload&amp;gt;): Promise&amp;lt;Payload&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now the view layer code looks like this:&lt;/p&gt;
&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;&lt;span class=&quot;token deleted-sign deleted&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;connection.sendMessage({ type: &quot;play&quot; /*...*/ })
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;trackMessage(connection.sendMessage({ type: &quot;play&quot; /*...*/ }))
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; .then(showSuccess)
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; .catch(showError);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;👌 rather easy to implement&lt;/li&gt;
&lt;li&gt;👌 a unit with a well defined responsibility (easy to test)&lt;/li&gt;
&lt;li&gt;👌 low impact on the view layer&lt;/li&gt;
&lt;li&gt;👌 no impact on the business logic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;👎 unfactorised (every call to &lt;code&gt;sendMessage&lt;/code&gt; need to be wrapped)&lt;/li&gt;
&lt;li&gt;👎 hard to disable (every call to &lt;code&gt;sendMessage&lt;/code&gt; need to be disabled)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;events-to-the-rescue&quot; tabindex=&quot;-1&quot;&gt;Events to the rescue&lt;/h2&gt;
&lt;p&gt;What we actually want is something that is completely transversal to our application code.
What if we could leave the view layer intact and have very limited impact on the business logic?&lt;/p&gt;
&lt;p&gt;Let&#39;s do an attempt based on events.&lt;/p&gt;
&lt;p&gt;Events are nice for decoupling entirely business and plug-in features (like our tracking).&lt;/p&gt;
&lt;p&gt;Let&#39;s go back to our &lt;code&gt;Connection&lt;/code&gt; class&lt;/p&gt;
&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;&lt;span class=&quot;token deleted-sign deleted&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;class Connection {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;class Connection extends EventTarget {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; //...
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; function sendMessage{
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   return new Promise((resolve, reject) =&gt; {
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     const messageId = uuid(); // We generate an id for that message
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     this.dispatchEvent(new CustomEvent(&#39;sendmessage&#39;, {detail: {id: messageId})));
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     peerConnection.send(msg);
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     function handleAck({ type, ackId, err }) {
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;       if (type === &quot;ack&quot; &amp;amp;&amp;amp; ackId === messageId) {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;         this.dispatchEvent(new CustomEvent(&#39;ackmessage&#39;, {detail: {id: messageId, err}}));
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;         peerConnection.removeMessageListener(handleAck);
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;         return !err ? resolve() : reject(err);
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;       }
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     }
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     peerConnection.addMessageListener(handleAck);
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;   });
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; }
&lt;/span&gt;&lt;/span&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our business code needed a few modifications, that&#39;s true, but these are quite generic changes that are unrelated to tracking. You can think of it this way: if you extract this module to an external library, &lt;strong&gt;it has no unexpected side effects&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now we can implement our monitoring module based on the &lt;code&gt;EventTarget&lt;/code&gt; contract we just defined (I believe TypeScript will help reading the following):&lt;/p&gt;
&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;monitorConnection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;connection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Connection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; timers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Map&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  connection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;sendmessage&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; detail &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; CustomEvent&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      timers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;trackMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;latency&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; timer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  connection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;ackmessage&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; detail &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; CustomEvent&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; err&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; timer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; timers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;trackMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;message_error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;trackMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;message_success&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;trackMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;latency&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; timer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally we need to plug that code somewhere. This time it is going to be in the glue code that instantiate the &lt;code&gt;Connection&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;const connection = new Connection(/*...*/);

&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;monitorConnection(connection);
&lt;/span&gt;&lt;/span&gt;
//...
connection.sendMessage(message);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;👌 factorised (all the monitoring logic is in a single place)&lt;/li&gt;
&lt;li&gt;👌 a unit with a well defined responsibility (easily testable)&lt;/li&gt;
&lt;li&gt;👌 low impact on the business logic&lt;/li&gt;
&lt;li&gt;👌 very low impact on the global codebase&lt;/li&gt;
&lt;li&gt;👌 trivial to deactivate (can be disabled by commenting/conditioning &lt;strong&gt;a single&lt;/strong&gt; line of the code)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;👎 slightly harder to implement (the matching of message ids need to be manually done)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Tracking is an excellent use case for &lt;code&gt;EventTarget&lt;/code&gt;. It allows for the business code to be very generic and the tracking mechanism to be very distant from your application code.&lt;/p&gt;
&lt;p&gt;In general &lt;code&gt;Events&lt;/code&gt; are tailored for those kind of scenarios: Having something that work in parallel to something else.
The &lt;code&gt;DOM&lt;/code&gt; API works this way!&lt;br /&gt;
The &lt;code&gt;DOM&lt;/code&gt; itself is made to display things but it allows us to hook into events that happen on the presentational layer. With a few &lt;code&gt;addEventListener&lt;/code&gt; we can add very complex behaviours on top of the &lt;code&gt;DOM&lt;/code&gt; but the &lt;code&gt;DOM&lt;/code&gt; never knows about those.&lt;/p&gt;
&lt;p&gt;This is the beauty of it, there is a generic contract (eg. &#39;I will send a &lt;code&gt;click&lt;/code&gt; event whenever the user clicks somewhere&#39; or &#39;I will send a &lt;code&gt;sendmessage&lt;/code&gt; event every time a message is being sent&#39;) that allows us, web developer, to add behavior on top of it.&lt;/p&gt;
&lt;p&gt;Word of caution, though, &lt;code&gt;Events&lt;/code&gt; are great but should not be overused. Keep in mind that they can blur the readability of the codebase if used for core behaviours. In those cases coupling is the way to go 🙂&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>You might not need this</title>
    <link href="https://blog.atomrc.dev/p/you-dont-need-this/"/>
    
    <updated>2017-05-30T00:00:00Z</updated>
    
    <published>2017-05-30T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/you-dont-need-this/</id>
    <content type="html">&lt;p&gt;Consider the following beauty:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Under the assumption that &lt;code&gt;compute&lt;/code&gt; is a &lt;strong&gt;pure function&lt;/strong&gt; (a function which will always return the same value given the same arguments. But not only, see &lt;a href=&quot;https://en.wikipedia.org/wiki/Pure_function&quot;&gt;Pure Function on Wikipedia&lt;/a&gt;), you can easily deduce an interesting thing from those 3 lines: &lt;em&gt;&lt;code&gt;compute&lt;/code&gt; will always return the same value&lt;/em&gt;.&lt;br /&gt;
&lt;code&gt;compute&lt;/code&gt; is, basically, &lt;strong&gt;a constant&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In JavaScript, it is very easy to break the purity of a function thus breaking the deduction we made earlier about &lt;code&gt;compute&lt;/code&gt; being a constant.&lt;/p&gt;
&lt;p&gt;One way to break purity, would be to read some external variable:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; ext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val &lt;span class=&quot;token comment&quot;&gt;// ext is some object defined in a parent scope&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... And that external variable could be &lt;code&gt;this&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We now have a way to change the returned value of &lt;code&gt;compute&lt;/code&gt; &lt;strong&gt;from outside the function&lt;/strong&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; compute
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1&lt;/span&gt;
a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 2 ... so long purity, you will be missed&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might be thinking that, at least, with a method call the bound object is never too far from the call, making it explicit that the returned value depends on that object (&lt;em&gt;maybe?&lt;/em&gt;)!&lt;br /&gt;
Most of the time, is it true. But it is easy to find a counter example:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ext &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// create a function bound to `ext`&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;compute&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1&lt;/span&gt;
ext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;the-misunderstood-this&quot; tabindex=&quot;-1&quot;&gt;The misunderstood &lt;code&gt;this&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt; is probably the most misunderstood concept of the JavaScript language.&lt;br /&gt;
People coming from classical Object Oriented Programming languages often mistaken &lt;code&gt;this&lt;/code&gt; for an instance of the class the method is in.&lt;/p&gt;
&lt;p&gt;A better definition of &lt;code&gt;this&lt;/code&gt; in JavaScript would be:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt; represents the object which &lt;em&gt;owns&lt;/em&gt; the method being called&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And, due to the dynamic nature of JavaScript, function ownerships often change at runtime.&lt;/p&gt;
&lt;p&gt;Functions are &lt;a href=&quot;http://ryanchristiani.com/functions-as-first-class-citizens-in-javascript/&quot;&gt;first class citizen in JavaScript&lt;/a&gt;, which means you can treat them as any other object: passing them around to functions or returning them.&lt;/p&gt;
&lt;p&gt;Due to the asynchronous nature of JavaScript, you actually pass functions around a lot.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/resource&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;callback&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- callback is a function&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the functions passed around are actually methods, they lose the binding with their initial object:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/resource&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;callback&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- `this` is undefined&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To fix this, you need to manually bind the method to its owning object:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/resource&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- `this` is defined again&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt; is such a mess for newcomers that TypeScript&#39;s documentation has an &lt;a href=&quot;https://github.com/Microsoft/TypeScript/wiki/%27this%27-in-TypeScript&quot;&gt;article dedicated to it&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;functions-are-about-logic%2C-this-is-about-state&quot; tabindex=&quot;-1&quot;&gt;Functions are about logic, &lt;code&gt;this&lt;/code&gt; is about state&lt;/h2&gt;
&lt;p&gt;So we can ask the question: What does &lt;code&gt;this&lt;/code&gt; do for us?&lt;/p&gt;
&lt;p&gt;Common response:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt; allows us to write logic close to our models. After all, this is what OOP is about.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The way I see it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt; allows us to write &lt;strong&gt;stateful functions&lt;/strong&gt;. It&#39;s a way to embed some state into a function&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In my opinion, &lt;strong&gt;functions should be building blocks that take some arguments and return a result depending on those arguments, and only those arguments&lt;/strong&gt;.&lt;br /&gt;
This is what functional programming is about (see &lt;a href=&quot;https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf&quot;&gt;Why Functional Programming Matters&lt;/a&gt;), and this is where the front-end is heading (&lt;a href=&quot;https://medium.com/javascript-scene/why-learn-functional-programming-in-javascript-composing-software-ea13afc7a257&quot;&gt;Why Learn Functional Programming in JavaScript? (Composing Software)&lt;/a&gt;, &lt;a href=&quot;https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0&quot;&gt;Master the JavaScript Interview: What is Functional Programming?&lt;/a&gt;, &lt;a href=&quot;http://ramdajs.com/&quot;&gt;Ramda&lt;/a&gt;, &lt;a href=&quot;https://lodash.com/&quot;&gt;lodash&lt;/a&gt;, &lt;a href=&quot;https://github.com/reactjs/redux&quot;&gt;Redux&lt;/a&gt; ...)&lt;/p&gt;
&lt;h2 id=&quot;the-separation-of-logic-and-state&quot; tabindex=&quot;-1&quot;&gt;The separation of logic and state&lt;/h2&gt;
&lt;p&gt;Getting rid of &lt;code&gt;this&lt;/code&gt; is as easy as replacing every occurrences of &lt;code&gt;this&lt;/code&gt; by a new parameter.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// becomes&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second version of &lt;code&gt;compute&lt;/code&gt; has some nice benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it is &lt;strong&gt;pure&lt;/strong&gt; (only depends on its inputs)*;&lt;/li&gt;
&lt;li&gt;its signature explicitly tells that it depends on some input &lt;code&gt;a&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, to remove &lt;code&gt;this&lt;/code&gt; from your functions you will also have to change every function calls. Not the funniest part, I agree.&lt;/p&gt;
&lt;p&gt;Getting rid of &lt;code&gt;this&lt;/code&gt; might feel a little scary and you might think you will lose powerful features. One nice feature I can think of is &amp;quot;method chaining&amp;quot;.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; transformed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;t&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;e&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;j&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toUpperCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you remove &lt;code&gt;this&lt;/code&gt; from those methods they become simple functions, and you need to transform that piece of code to:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; transformed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toUpperCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;e&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;j&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;t&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Definitely not as sexy as method chaining, right? And that&#39;s where functional programming concepts come handy and &lt;a href=&quot;http://ramdajs.com/&quot;&gt;Ramda&lt;/a&gt; (or &lt;a href=&quot;https://lodash.com/&quot;&gt;Lodash&lt;/a&gt;) are very powerful allies.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;R&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ramda&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; removeT  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;t&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; e2j      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;e&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;j&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; testToJS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;toUpperCase&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e2j&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; removeT&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    ^ testToJS is a completly new function created&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// from the composition of the removeT, e2j and toUpperCase functions&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; transformed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;testToJS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note how this last example has make very nice and clear separation between logic and data. Only the last line is dealing with data (read &amp;quot;state&amp;quot;) while all the other lines of code are here to describe logic. The separation of concerns is perfectly respected :)&lt;/p&gt;
&lt;p&gt;* &lt;em&gt;not using &lt;code&gt;this&lt;/code&gt; inside your functions doesn&#39;t imply that they are pure at all. You still need to avoid any side effect in order to achieve purity.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Taking away &lt;code&gt;this&lt;/code&gt; from your developer&#39;s life is a great opportunity for you to leverage the full power of functions and finally start diving into &lt;strong&gt;functional programming&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In the process, you will learn how to write very simple functions and compose them together to create fully functional user interfaces.&lt;/p&gt;
&lt;p&gt;I personally don&#39;t like &lt;code&gt;this&lt;/code&gt; and try to avoid it as much as I can.&lt;br /&gt;
But, don&#39;t get me wrong, &lt;code&gt;this&lt;/code&gt; is not evil and most JavaScript developers know how to deal with it.&lt;br /&gt;
Sometime you don&#39;t really have the luxury of being able to choose to use it or not. If you use React, for example, any &lt;a href=&quot;https://facebook.github.io/react/docs/state-and-lifecycle.html#adding-local-state-to-a-class&quot;&gt;&lt;strong&gt;stateful&lt;/strong&gt; component&lt;/a&gt; you will write will have to use &lt;code&gt;this&lt;/code&gt; (which make sense when you have in mind that &lt;code&gt;this&lt;/code&gt; is about state).&lt;/p&gt;
&lt;p&gt;That being said, removing &lt;code&gt;this&lt;/code&gt; will allow you to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;make your function signatures more explicit;&lt;/li&gt;
&lt;li&gt;isolate your state and models from your logic;&lt;/li&gt;
&lt;li&gt;avoid any unexpected behavior due to the misunderstanding of the &lt;code&gt;this&lt;/code&gt; concept.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, it&#39;s seems like a perfect excuse to finally learn to love functions and to dive into functional programming :)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Cycle.js, RxJS and cold observables</title>
    <link href="https://blog.atomrc.dev/p/cyclejs-rx-newbie-trap/"/>
    
    <updated>2016-05-05T00:00:00Z</updated>
    
    <published>2016-05-05T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/cyclejs-rx-newbie-trap/</id>
    <content type="html">&lt;p&gt;Lately, I fell into a pretty tough &lt;a href=&quot;https://github.com/Reactive-Extensions/RxJS&quot;&gt;RxJS&lt;/a&gt; beginner trap while playing around with &lt;a href=&quot;http://cycle.js.org/&quot;&gt;Cycle.js&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is the situation I was in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a parent component that creates a child component depending on a data stream;&lt;/li&gt;
&lt;li&gt;a child component that outputs an &lt;code&gt;action$&lt;/code&gt; stream that is used in the parent component (depending on DOM events).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the symptoms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the child component renders perfectly;&lt;/li&gt;
&lt;li&gt;I get the expected output if I subscribe to the &lt;code&gt;action$&lt;/code&gt; stream &lt;strong&gt;from inside the child component&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;action$&lt;/code&gt; stream does not output anything &lt;strong&gt;from the parent component&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The reason for that weird behavior: the way &lt;strong&gt;cold observables&lt;/strong&gt; work (and, of course, the fact that I didn&#39;t took the time to read and understand the RxJS doc ... :( )&lt;/p&gt;
&lt;p&gt;NB: As I am writing this article, Cycle.js is being generalized to work with any stream library (see &lt;a href=&quot;https://github.com/cyclejs/core/issues/196&quot;&gt;Cycle.js Diversity&lt;/a&gt;) and a stream library, specially designed for Cycle.js, is currently being built: &lt;a href=&quot;http://staltz.com/why-we-built-xstream.html&quot;&gt;xstream&lt;/a&gt;. As xtream will be hot-observable-only, this article won&#39;t be relevant any more :)&lt;/p&gt;
&lt;h2 id=&quot;tldr&quot; tabindex=&quot;-1&quot;&gt;TLDR&lt;/h2&gt;
&lt;p&gt;Keep in mind that :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cold observables replay the complete observable chain for each subscriber;&lt;/li&gt;
&lt;li&gt;before diving into Cycle.js be sure you know and understand all the different types of observables;&lt;/li&gt;
&lt;li&gt;just read this &lt;a href=&quot;http://reactivex.io/rxjs/manual/overview.html#subject&quot;&gt;introduction to observables&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;also, have a look at this great &lt;a href=&quot;https://gist.github.com/staltz/868e7e9bc2a7b8c1f754&quot;&gt;introduction to reactive programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-situation&quot; tabindex=&quot;-1&quot;&gt;The situation&lt;/h2&gt;
&lt;p&gt;Ok let&#39;s go a little deeper into my newbie-trap.&lt;/p&gt;
&lt;p&gt;Here is a simplified version of the situation I had.&lt;/p&gt;
&lt;p&gt;The child component:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;UserContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; user$&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; logAction$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;DOM&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.log&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;log&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;//this prints an output each time the button is clicked&lt;/span&gt;
    logAction$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/*log*/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//the DOM output of the component&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;DOM&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; user$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.user-name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.log&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Log&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//the &#39;log&#39; stream that is used in the parent&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;logAction$&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; logAction$
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;main&lt;/code&gt; function that creates the child component:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; user$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Observable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;just&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;felix&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;//we map the user stream to an &#39;instance&#39; of a UserContainer&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; userContainer$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; user$
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
          &lt;span class=&quot;token comment&quot;&gt;//from @cycle/isolate https://github.com/cyclejs/isolate&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;isolate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UserContainer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;DOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;user$&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Observable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;just&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;//keep a trace of the DOM evolution for the UserContainer component&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; userContainerDOM$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; userContainer$
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; container&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;//keep a link to the log action of the UserContainer&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; userContainerLogAction$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; userContainer$
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;flatMapLatest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; container&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logAction$&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/*
     * /!&#92; here is the problem, this will never print anything
     * when the button is clicked !!
     */&lt;/span&gt;
    userContainerLogAction$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/*log*/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;DOM&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; userContainerDOM$
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want to play with it, here is a &lt;a href=&quot;https://jsbin.com/ropaqa/edit?js,console,output&quot;&gt;jsbin I created to reproduce the bug&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To summary the symptoms I had:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I had no trouble receiving &lt;code&gt;click&lt;/code&gt; events if I subscribe from inside the child component namely &lt;code&gt;UserContainer&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;for some reason I could receive any &lt;code&gt;click&lt;/code&gt; events from the function where I build the &lt;code&gt;UserContainer&lt;/code&gt; component.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-ridiculously-simple-solution&quot; tabindex=&quot;-1&quot;&gt;The ridiculously simple solution&lt;/h2&gt;
&lt;p&gt;So – without any more suspense – here is the ridiculously simple solution:&lt;/p&gt;
&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;const userContainer$ = user$
&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; .map(user =&gt;
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     //from @cycle/isolate https://github.com/cyclejs/isolate
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt;     isolate(UserContainer)({ DOM, user$: Observable.just(user) })
&lt;/span&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token line&quot;&gt; .shareReplay(1)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;explanation&quot; tabindex=&quot;-1&quot;&gt;Explanation&lt;/h2&gt;
&lt;p&gt;Fixing a bug is a good thing, understanding it is a lot more valuable ;) So here is the explanation for that bug.&lt;/p&gt;
&lt;p&gt;The main reason for that behavior is: the &lt;strong&gt;way cold observable work&lt;/strong&gt; in RxJS. In fact a cold observable replays the whole observable sequence for each subscriber it has.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; values$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Observable
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;just&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//this is a cold observable&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;here I am&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;/* /!&#92; just for the exemple.
         * always avoid doing non deterministic
         * calls in your app&#39;s code
         */&lt;/span&gt;
        Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

value$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;first sub: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
value$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;second sub: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/* output:
 * Here I am
 * first sub: 7
 * Here I am
 * second sub: 5
 */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can the, the log &lt;code&gt;Here I am&lt;/code&gt; is printed twice and the first subscriber doesn&#39;t get the same value as the second subscriber (resp &lt;code&gt;7&lt;/code&gt; and &lt;code&gt;5&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;I my case I have that piece of code that is building the &lt;code&gt;UserContainer&lt;/code&gt; component:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; userContainer$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; user$
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;isolate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UserContainer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;user$&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Observable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;just&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And two streams that originate from the &lt;code&gt;userContainer$&lt;/code&gt; stream:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; userContainerDOM$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; userContainer$
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; container&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; userContainerLogAction$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; userContainer$
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;flatMapLatest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; container&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logAction$&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;when &lt;code&gt;userContainerDOM$&lt;/code&gt; is subscribed it creates a new &lt;code&gt;UserContainer&lt;/code&gt; component (from the &lt;code&gt;userContainer$&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;when &lt;code&gt;userContainerLogAction$&lt;/code&gt; is subscribed it creates a new &lt;code&gt;UserContainer&lt;/code&gt; component (from the &lt;code&gt;userContainer$&lt;/code&gt;);&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which means that each stream has access to a different &amp;quot;instance&amp;quot; of &lt;code&gt;UserContainer&lt;/code&gt; and that the log action we retrieve does not come from the same component as the DOM.&lt;br /&gt;
In other words: we subscribe to events of a component that is not displayed on screen and, as such, does not receive any DOM event**.&lt;br /&gt;
**this last statement is only true because the UserContainer is isolated (see &lt;a href=&quot;https://github.com/cyclejs/isolate&quot;&gt;@cycle/isolate&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Now the &lt;code&gt;shareReplay(1)&lt;/code&gt; solution transforms the observable into a &lt;strong&gt;hot observable&lt;/strong&gt;. This means the whole subscription sequence will only be executed once per value produced by the stream &lt;code&gt;user$&lt;/code&gt;. We also keep the last produced value for further subscriber to get that value when they subscribe.&lt;br /&gt;
Which means that now, we are only creating a single &lt;code&gt;UserContainer&lt;/code&gt; per value produced by the &lt;code&gt;user$&lt;/code&gt; stream and that all the underlying subscribers will work on the same &amp;quot;instance&amp;quot; of that &lt;code&gt;UserContainer&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Cycle.js beginners need to overcome a pretty huge obstacle before embracing the power of Cycle.js: RxJS. Don&#39;t get me wrong, RxJS is a great library it&#39;s just not perfectly suited for the idea behind Cycle.js.&lt;/p&gt;
&lt;p&gt;There is very little to learn about Cycle.js, it is more of an idea more than a complete library/framework. Once you get the idea behind Cycle.js (which is pretty easy) what you have to learn is &lt;strong&gt;RxJS&lt;/strong&gt;. Be sure you know the different operators (at least those inside &lt;a href=&quot;https://github.com/Reactive-Extensions/RxJS/blob/master/doc/libraries/lite/rx.lite.md&quot;&gt;rx.lite.js&lt;/a&gt;) and, most importantly, be sure that you &lt;strong&gt;understand what are observables&lt;/strong&gt; by reading this &lt;a href=&quot;http://reactivex.io/rxjs/manual/overview.html#subject&quot;&gt;introduction to observables&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One last thing, don&#39;t hesitate to ask questions on the &lt;a href=&quot;https://gitter.im/cyclejs/core&quot;&gt;Cycle.js&#39;s gitter chan&lt;/a&gt; ;)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Quelques questions courantes avec Flux</title>
    <link href="https://blog.atomrc.dev/p/flux-questions/"/>
    
    <updated>2015-11-08T00:00:00Z</updated>
    
    <published>2015-11-08T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/flux-questions/</id>
    <content type="html">&lt;p&gt;Lors de ma découverte de Flux, je me suis posé un certain nombre de questions. Je voudrais vous les exposer ici, pas simplement parce que vous risquez de vous les poser mais surtout parce que les réponses mettent en valeur les principes de Flux.&lt;/p&gt;
&lt;h2 id=&quot;o%C3%B9-faire-mes-requ%C3%AAtes-ajax-%3F&quot; tabindex=&quot;-1&quot;&gt;Où faire mes requêtes AJAX ?&lt;/h2&gt;
&lt;p&gt;Réponse courte : dans les créateurs d&#39;actions.&lt;/p&gt;
&lt;p&gt;Explication : On pourrait penser que les stores sont responsables des requêtes AJAX, seulement la doc de Flux nous dit que les stores doivent être synchrones. Donc à partir de là on devrait accepter que l&#39;AJAX ne se fait pas dans les stores, mais allons un peu plus loin pour en être complétement convaincu.&lt;/p&gt;
&lt;p&gt;On va raisoner par l&#39;absurde pour répondre à cette question. Flux nous dit que les stores représentent un état de l&#39;application à l&#39;instant &lt;code&gt;t&lt;/code&gt;. Si on garde en tête qu&#39;un changement d&#39;état de votre application est en réalité une fonction qui prend en paramètres l&#39;état &lt;code&gt;t&lt;/code&gt; et une action. Admettons donc qu&#39;une action déclenche une requête AJAX dans l&#39;un de vos stores. Au moment du dispatch de l&#39;action, les données du store sont dans un certain état et changent une fois la requête terminée. Or il n&#39;y a pas eu de nouvelle action déclenchée au moment du retour de la requête donc votre application n&#39;a pas changée d&#39;état alors que les données de votre store si. Ce qui veut dire que à l&#39;instant &lt;code&gt;t&lt;/code&gt; de l&#39;application votre store peut être dans deux états différents, ce qui est incohérent avec le postulat de base.&lt;/p&gt;
&lt;h2 id=&quot;comment-nommer-mes-actions-%3F&quot; tabindex=&quot;-1&quot;&gt;Comment nommer mes actions ?&lt;/h2&gt;
&lt;p&gt;Réponse courte : il faut se poser la question « Que vient-il de se passer sur mon application ? »&lt;/p&gt;
&lt;p&gt;Explication : Il faut voire les actions comme des éléments stupides. elles sont là pour informer de ce qu&#39;il se passe et, en aucun cas, décider de ce qu&#39;il faut faire quand quelque chose se produit. Il faut considérer qu&#39;elles ne connaissent rien de l&#39;application dans laquelle elles évoluent et n&#39;ont aucune idée de ce qu&#39;il va se passer quand elle vont émettre un évènement.&lt;/p&gt;
&lt;p&gt;Les actions doivent donc pas ressembler à &lt;code&gt;SHOW_TODOS&lt;/code&gt; mais plutôt &lt;code&gt;TODOS_RECEIVED&lt;/code&gt;. De manière générale &lt;strong&gt;construire ses noms d&#39;actions au passé&lt;/strong&gt; aide ;)&lt;/p&gt;
&lt;h2 id=&quot;comment-choisir-entre-un-composant-statefull-ou-un-nouveau-store-%3F&quot; tabindex=&quot;-1&quot;&gt;Comment choisir entre un composant statefull ou un nouveau store ?&lt;/h2&gt;
&lt;p&gt;La réponse par défaut est : faites un store. Selon mon opinion, le seul cas de figure ou un composant statefull est envisageable serait pour un composant très gérénique qui n&#39;a aucune logique métier liée à votre application et que vous pouriez utiliser sur un projet qui n&#39;a rien à voir.&lt;/p&gt;
&lt;p&gt;Par exemple, si vous faites un date picker générique, à mon sens il est plutôt conseillé de faire un composant statefull. En revanche le composant métier qui utilisera votre date picker devra avoir son store.&lt;/p&gt;
&lt;p&gt;Le point faible de cette réponse est qu&#39;elle rentre en contradiction avec la réponse à la première question. A l&#39;ouverture de votre date picker l&#39;état change visuellement sans qu&#39;il y ai eu changement d&#39;état de l&#39;application.&lt;br /&gt;
On peut répondre à ça que ça n&#39;est pas un changement d&#39;état de l&#39;application puisque les objets métier n&#39;ont pas changés. Au même titre qu&#39;on ne stocke pas dans un store l&#39;état du scroll du user ou encore la position de sa souris.&lt;/p&gt;
&lt;h2 id=&quot;%C3%A0-vous&quot; tabindex=&quot;-1&quot;&gt;À vous&lt;/h2&gt;
&lt;p&gt;Bref voila les quelques questions qui m&#39;ont fait réfléchir en me penchant sur Flux. J&#39;espère qu&#39;elles vous seront utiles et qu&#39;elles vous permettrons de mieux penser en Flux.&lt;br /&gt;
N&#39;hésitez pas à partager les questions qui vont ont fait cogiter et à rebondir sur les réponses que j&#39;apporte ici.&lt;/p&gt;
&lt;p&gt;A bon entendeur ;)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Le guide que j&#39;aurais aimé avoir quand j&#39;ai commencé Flux</title>
    <link href="https://blog.atomrc.dev/p/react-flux/"/>
    
    <updated>2015-10-19T00:00:00Z</updated>
    
    <published>2015-10-19T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/react-flux/</id>
    <content type="html">&lt;p&gt;En commençant &lt;a href=&quot;https://facebook.github.io/flux/docs/overview.html#content&quot;&gt;Flux&lt;/a&gt;, j&#39;avoue avoir eu beaucoup de moments de confusion et questions inutiles qui me sont venus à l&#39;esprit. La majorité des questions que je me posais venaient de la confusion qu&#39;il est facile de faire entre la &lt;a href=&quot;https://facebook.github.io/flux/docs/overview.html#content&quot;&gt;présentation de Flux&lt;/a&gt; et le &lt;a href=&quot;https://github.com/facebook/flux&quot;&gt;Github de Flux&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Je vous propose donc de revenir un peu sur la source de ma confusion puis de reprendre, avec les idées au clair, les concepts de Flux emsemble.&lt;/p&gt;
&lt;h2 id=&quot;pourquoi-j&#39;ai-%C3%A9t%C3%A9-confus-par-flux&quot; tabindex=&quot;-1&quot;&gt;Pourquoi j&#39;ai été confus par Flux&lt;/h2&gt;
&lt;p&gt;La majeure partie de ma confusion venait du fait que je n&#39;avais pas bien compris de quoi la doc traitait.&lt;br /&gt;
Le souci c&#39;est qu&#39;une partie de la doc parle du concept de Flux en montrant des exemple de code (c&#39;est le cas du sempiternel exemple de la TODO list) alors que d&#39;autres parties de la doc parlent de l&#39;&lt;a href=&quot;https://facebook.github.io/flux/docs/dispatcher.html#content&quot;&gt;implémentation que Facebook utilise&lt;/a&gt; et dont on trouve le code sur Github.&lt;/p&gt;
&lt;p&gt;Je n&#39;arrivais pas à voir que Flux n&#39;était pas un framework ni une librairie mais juste un concept. Aussi je prenais la doc comme si c&#39;était la documentation de leur &lt;a href=&quot;https://github.com/facebook/flux&quot;&gt;implémentation de Flux&lt;/a&gt;, or pas uniquement. Seulement, quand vous lisez cette doc dans cet état d&#39;esprit, vous voyez des incohérences partout et vous finissez par vous enerver.&lt;/p&gt;
&lt;p&gt;Du coup, pour lire la suite de cet article mettez vous bien en tête que :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flux n&#39;est pas du code mais un concept ;&lt;/li&gt;
&lt;li&gt;les exemples de code ici n&#39;utilisent aucune implémentation de Flux particulière.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sachez qu&#39;il existe un grand nombre d&#39;implémentations de Flux qui se baladent avec de solides documentations. Je vous invite à consulter ce site qui vous montrera un peu les tendances d&#39;utilisation des différentes implémentations : &lt;a href=&quot;https://github.com/kriasoft/react-starter-kit/issues/22&quot;&gt;Which Flux implementation should I use?&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;le-probl%C3%A8me-que-r%C3%A9sout-flux&quot; tabindex=&quot;-1&quot;&gt;le problème que résout Flux&lt;/h2&gt;
&lt;p&gt;Dans le modèle MVC classique, vous avez votre modèle (les données brutes) vos contrôleurs (qui passent les données aux vues et qui récupèrent les actions des vues pour mettre à jour le modèle) et vos vues (qui s&#39;occupent simplement d&#39;afficher les donnés calculées dans un template et d&#39;envoyer des évènements aux contrôleurs).
Le souci de ce schéma est que vos contrôleurs font beaucoup trop de choses dans votre application. Les vrais problèmes commencent à apparaitre quand vous commencez à avoir un contrôleur qui gère un type de données et plusieurs vues qui affichent cette même donnée.&lt;/p&gt;
&lt;p&gt;La &lt;a href=&quot;https://www.youtube.com/watch?list=PLb0IAmt7-GS188xDYE-u1ShQmFFGbrk0v&amp;amp;v=nYkdrAPrdcw#t=621&quot;&gt;petite histoire que raconte Facebook&lt;/a&gt; pour expliquer le problème que résout Flux parle du chat.&lt;br /&gt;
La première version n&#39;est qu&#39;un petit panel en bas de page, c&#39;est tout. À ce moment là, c&#39;est simplement un petit composant MVC et dispose de son contrôleur.
Ce contrôleur s&#39;occupe de recevoir les messages et récupère les évènements du panel pour envoyer les messages.
Si on devait écrire, de façon très synthétique, la méthode de contrôleur qui gère les nouveaux messages on aurait sûrement quelque chose comme ça :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; chatPanel &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getChatPanel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;thread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    chatPanel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Puis est arrivé le bandeau de notification en &lt;em&gt;topbar&lt;/em&gt; de Facebook, celle-ci indique (entre autres) le nombre de messages non lus dans le chat. Le code du contrôleur se complexifie alors un peu pour devenir.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; chatPanel &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getChatPanel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;thread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    chatPanel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    chatNotif&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;increase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chatPanel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hasFocus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//si le chat a le focus, on peut décrémenter la notif&lt;/span&gt;
        chatNotif&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decrease&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enfin est arrivé la page de chat dédiée, sur laquelle les deux précédents composants peuvent bien sûr être présents.
Notre nouveau code ressemble maintenant à :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; chatPanel &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getChatPanel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;thread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    chatPanel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    chatNotif&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;increase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chatPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentThread &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;thread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//si la page de chat est ouverte sur la conversation&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//on ajoute le message&lt;/span&gt;
        chatPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chatPanel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hasFocus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; chatPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentThread &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;thread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        chatNotif&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decrease&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bon je pense que vous voyez l&#39;idée, plus on rajoute de vues associées à ces données, plus on va rendre nos contrôleurs complexes. Ce qui veut dire un code plus dur à maintenir et à comprendre.&lt;br /&gt;
Notez que vous avez aussi à traiter tous les événements qui peuvent être liés à cette messagerie (focus sur chacune des vues et quand l&#39;utilisateur répond par exemple).&lt;/p&gt;
&lt;p&gt;Le problème de fond est : &lt;strong&gt;le contrôleur est responsable de beaucoup trop de choses&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Flux répond à ça en deux points assez simples :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un &lt;strong&gt;flux d&#39;actions unidirectionnel&lt;/strong&gt; ;&lt;/li&gt;
&lt;li&gt;la fin de la séparation des vues et contrôleurs au profit de &lt;strong&gt;controller-views&lt;/strong&gt; responsables de transformer les données qu&#39;ils affichent.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;flux&quot; tabindex=&quot;-1&quot;&gt;Flux&lt;/h2&gt;
&lt;p&gt;La principale idée de flux est de faire passer le moindre évènement de votre application au travers d&#39;une boucle qui va parcourir tous vos stores (les éléments qui contiennent les données de votre application, nous reviendrons dessus juste après).&lt;br /&gt;
Si vous allez voire le &lt;a href=&quot;https://github.com/facebook/flux/tree/master/src&quot;&gt;code de Flux&lt;/a&gt; vous vous rendrez compte qu&#39;il ne se compose en fait que d&#39;un dispatcher (et de quelques helpers). Car en réalité &lt;strong&gt;Flux n&#39;est pas du code mais plutôt une nouvelle façon de penser son code&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Avec Flux votre codebase va se décomposer de la façon suivante :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;des &lt;strong&gt;stores&lt;/strong&gt; qui sont l&#39;endroit où votre modèle va être contenu ;&lt;/li&gt;
&lt;li&gt;des &lt;strong&gt;actions&lt;/strong&gt; qui représente toutes les choses que votre appli peut faire ;&lt;/li&gt;
&lt;li&gt;un (et un seul) &lt;strong&gt;dispatcher&lt;/strong&gt; qui notifie les stores des actions effectuées ;&lt;/li&gt;
&lt;li&gt;des &lt;strong&gt;controller-views&lt;/strong&gt; qui vont transformer et afficher les données qu&#39;on leur donne.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;les-stores&quot; tabindex=&quot;-1&quot;&gt;Les stores&lt;/h3&gt;
&lt;p&gt;C&#39;est ici que tout vos modèles vont vivre. Les stores sont en fait une représentation complète de l&#39;état, à un instant &lt;code&gt;t&lt;/code&gt;, de votre application. Il ne doit y avoir &lt;strong&gt;aucun de vos modèles qui vit en dehors d&#39;un store&lt;/strong&gt;.&lt;br /&gt;
Si vous vous pliez à cette règle, il vous suffira de faire une sauvegarde des données de vos stores et la recharger plus tard pour pouvoir retrouver l&#39;application dans l&#39;état exact dans laquelle vous l&#39;aviez laissée.&lt;/p&gt;
&lt;p&gt;Les stores se comportent comme un modèle observable (il dispose de getters et d&#39;une méthode addListener) à la différence près qu&#39;&lt;strong&gt;il n&#39;a pas de setter&lt;/strong&gt;. Et cela nous mène à une autre idée très importante dans Flux : &lt;strong&gt;seul le store peut mettre à jour ses propres données&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;À ce stade vous vous demandez donc normalement comment faire pour pouvoir changer l&#39;état de l&#39;application si on a aucun setter dans notre entité qui contient tous les modèles de l&#39;application. C&#39;est à ce moment là que le &lt;strong&gt;dispatcher&lt;/strong&gt; entre en jeux.&lt;/p&gt;
&lt;h3 id=&quot;le-dispatcher&quot; tabindex=&quot;-1&quot;&gt;Le dispatcher&lt;/h3&gt;
&lt;p&gt;Le dispatcher est là pour faire transiter &lt;strong&gt;absolument tout ce qu&#39;il se passe sur l&#39;application par vos stores&lt;/strong&gt;. Quand je parle de tout ce qui se passe, je parle bien sûr des évènements. Les évènements c&#39;est par exemple :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;« l&#39;utilisateur a cliqué sur le bouton de suppression »&lt;/li&gt;
&lt;li&gt;« l&#39;utilisateur a soumit tel formulaire »&lt;/li&gt;
&lt;li&gt;mais aussi « le serveur a envoyé telle donnée »&lt;/li&gt;
&lt;li&gt;ou encore « le serveur a indiqué que les identifiants de connexion sont faux ».&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bref, quand je dis tout ce qu&#39;il se passe, c&#39;est tout.&lt;/p&gt;
&lt;p&gt;Dans le bootstrap de votre application tous vos stores devront donc être enregistrés auprès de ce dispatcher unique qui les préviendra alors dès qu&#39;il se passe quelque chose sur l&#39;applications.&lt;br /&gt;
Le dispatcher est là pour crier bêtement à tous les stores « hey les gars il s&#39;est passé ceci, faites en ce que vous en voulez ». Son rôle s&#39;arrête là.&lt;/p&gt;
&lt;p&gt;Par la suite, vos stores eux choisissent de réagir, ou non, aux évènements qu&#39;ils reçoivent. Pour ça, votre store va donner un &lt;em&gt;callback&lt;/em&gt; à votre dispatcher qui sera appelé à chaque évènement. Souvent ce callback sera composé d&#39;un switch qui va traiter uniquement les cas qui l’intéresse.&lt;/p&gt;
&lt;p&gt;Allez, un peu de concret avec un petit bout de code pour illustrer tout ça. Imaginons un store qui garde bien au chaud en mémoire une liste de ... TODOS (et merde, je m&#39;étais juré que je ne prendrais pas cet exemple  … :/ )&lt;/p&gt;
&lt;p&gt;On dispose d&#39;un côté d&#39;une liste d&#39;évènements sous forme de constantes&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; events &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//quand l&#39;application reçoit une liste de todos du serveur (ou d&#39;ailleurs)&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;RECEIVED_TODOS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;RECEIVED_TODOS&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;//quand l&#39;utilisateur ajoute un nouveau todo&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;TODO_ADDED&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;TODO_ADDED&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;//quand les todos ont été sauvegardés sur le serveur&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;TODOS_SAVED&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;TODOS_SAVED&quot;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//[...] plein d&#39;autres évènements que nous ne traiterons pas ici&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; events&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;et de notre store qui gère les todos :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//l&#39;instance unique de notre dispatcher de l&#39;application&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; appDispatcher &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;../dispatcher/appDispatcher&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//les évènements définis précédemment&lt;/span&gt;
    events &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;./events&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//nos todos. inaccessibles depuis l&#39;extérieur et vide pour le moment&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//c&#39;est une action qui viendra remplir tout ça&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; todos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; TodosStore &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//l&#39;unique méthode accessible depuis l&#39;extérieur&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//qui nous retourne simplement les todos&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; todos&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;//ps il faut rajouter ici les méthodes d&#39;ajout/suppresion&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//d&#39;event listeners (addListener/removeListener)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//qui serviront pour prévenir les vues que quelque chose&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//a changé&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//c&#39;est ici que la magie s’opère. On enregistre un callback qui sera appelé dès que quelque chose se passe&lt;/span&gt;
appDispatcher&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//dans le payload on a tous les détails de l&#39;évènement (type et données qui va avec)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; action &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;actionType&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;//on répond uniquement aux évènements qui nous intéressent&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//quand on reçoit les todos, on remplace simplement nos todos&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//par les todos reçus&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; events&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;RECEIVED_TODOS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
            todos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;todos&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;emitChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//stay tuned, on parle de ça bientôt&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//quand un todo est créé sur le serveur on l&#39;ajoute dans notre &lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//liste de todos&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; events&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;TODO_ADDED&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
            todos&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;todo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//on ajoute la nouvelle todo dans la liste&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;emitChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//stay tuned, on parle de ça bientôt&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//par défaut, on ne fait rien&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//vous noterez par exemple qu&#39;on ne répond pas ici &lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//à l&#39;évènement TODOS_SAVED car il n&#39;aurait aucune influence&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//sur les données brute de ce store&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;todosStore&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; todosStore&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ça y est nous avons de quoi stocker nos données dans l&#39;application mais rien ni pour les afficher ni pour les remplir. Je vous propose donc de parler des vues avant de finir sur les actions.&lt;/p&gt;
&lt;h3 id=&quot;les-vues&quot; tabindex=&quot;-1&quot;&gt;Les vues&lt;/h3&gt;
&lt;p&gt;Allez maintenant qu&#39;on sait comment stocker nos données, voyons un peu comment les afficher. Pour ça, on va utiliser les controller-views.&lt;br /&gt;
L&#39;idée principale du controller-view est de regrouper ensemble le contrôleur et sa vue associée. Ainsi on se débarrasse d&#39;une partie du problème qu&#39;introduit Facebook avec son chat : &lt;strong&gt;le contrôleur responsable de beaucoup de vues&lt;/strong&gt;.&lt;br /&gt;
Facebook distingue tout de même deux type de vues différentes dans Flux : les views simples et les containers.&lt;/p&gt;
&lt;p&gt;Dans la suite de ce paragraphe, je vais considérer qu&#39;on utilise &lt;a href=&quot;https://facebook.github.io/react/docs/getting-started.html&quot;&gt;React&lt;/a&gt; pour faire nos vues, et que vous avez une connaissance des &lt;a href=&quot;https://facebook.github.io/react/docs/getting-started.html&quot;&gt;concepts de base de React&lt;/a&gt;. Sachez que rien ne vous oblige à utiliser React pour vos vues.&lt;/p&gt;
&lt;h4 id=&quot;les-containers&quot; tabindex=&quot;-1&quot;&gt;les containers&lt;/h4&gt;
&lt;p&gt;Les containers sont des controller-views un peu spéciaux : ils écoutent les changements d&#39;un store.&lt;br /&gt;
L&#39;idée du container est de centraliser les données relatives à une partie de votre application à un seul endroit. Le container passera ensuite ces données à ses enfants pour affichage.&lt;br /&gt;
Pour reprendre le cas de notre application de TODOS on va avoir envie d&#39;avoir un container qui à accès à l&#39;utilisateur loggé et un autre qui s&#39;occupe des TODOS. Ils écouteront respectivement les &lt;code&gt;userStore&lt;/code&gt; et &lt;code&gt;todosStore&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Vous l’aviez peut-être vu dans le callback passé au dispatcher dans mon exemple précédent, on voit le todosStore appeler la méthode &lt;code&gt;emitChange&lt;/code&gt;. En réalité, c’est cette méthode qui va permettre aux stores de prévenir les vues que des choses ont changées chez eux. Aussi quand vous créez un nouveau container, vous devez enregistrer un callback auprès des stores dont il dépend (et ne pas oublier de le détruire quand le composant est détruit). Avec React on fait ça dans le &lt;code&gt;componentWillMount&lt;/code&gt; ce qui nous donne&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;componentWillMount&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;token comment&quot;&gt;// à la création du composant, on enregistre le listener&lt;/span&gt;
         userStore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onChange&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token function-variable function&quot;&gt;componentWillUnmount&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;token comment&quot;&gt;// à la suppression du composant, on retire le listener&lt;/span&gt;
        userStore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;removeListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onChange&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;//ce callback est appelé à chaque fois que le userStore change&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;onChange&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; userStore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token function-variable function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//on a ici la dernière valeur du user&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;App user&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Comme son nom l&#39;indique, le container ne fait que contenir des données. Et, à ce titre, comme vous pouvez le voir dans le code précédent, la méthode &lt;code&gt;render&lt;/code&gt; est la plus simple possible. Elle délègue simplement le rendu à un composant de vue … Et c’est tout !&lt;/p&gt;
&lt;p&gt;Ainsi, vos container ne sont responsables que d&#39;une seule chose : mettre à jour les données pour tout le reste des composants. On respecte bien le fameux &lt;a href=&quot;https://en.wikipedia.org/wiki/Single_responsibility_principle&quot;&gt;Single Responsability Principle&lt;/a&gt; et le débug ne s&#39;en porte que mieux.&lt;/p&gt;
&lt;h4 id=&quot;les-controller-views&quot; tabindex=&quot;-1&quot;&gt;Les controller-views&lt;/h4&gt;
&lt;p&gt;Les controller-views ne sont là que pour transformer vos données brutes et les afficher comme vous le voulez. Il reçoivent donc toutes leurs données via des propriétés et sont censés être complètement &lt;em&gt;stateless&lt;/em&gt;.&lt;br /&gt;
On retrouve, avec les vues, un concept propre à la programmation fonctionnelle : une fonction retournera toujours le même résultat si on lui donne les mêmes paramètres. On appelle ça les &lt;a href=&quot;https://fr.wikipedia.org/wiki/Fonction_pure&quot;&gt;fonctions pures&lt;/a&gt;.&lt;br /&gt;
D&#39;ailleurs avec la &lt;a href=&quot;https://facebook.github.io/react/blog/2015/09/10/react-v0.14-rc1.html#changelog&quot;&gt;nouvelle syntaxe de composant&lt;/a&gt; que React v0.14 a introduit récemment, vous pouvez déclarer un composant comme étant une simple fonction qui prend en paramètre des &lt;code&gt;props&lt;/code&gt; et retourne du JSX. Avec cette syntaxe, pas de &lt;code&gt;state&lt;/code&gt; et on est alors obligé de faire un composant &lt;em&gt;stateless&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Pour reprendre notre application de TODOS qu&#39;on a commencé plus tôt, voila à quoi pourrait ressembler notre composant &lt;code&gt;App&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;header&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstname&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastname&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;LogoutButton user&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TodoContainer &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note : les composant-fonctions sont les composants les plus simples qu&#39;on puisse trouver. Pas d&#39;event handler dedans, de mixin ni de réécriture de &lt;a href=&quot;https://facebook.github.io/react/docs/component-specs.html#lifecycle-methods&quot;&gt;méthode du cycle de vie du composant&lt;/a&gt; (comme &lt;code&gt;componentWillMount&lt;/code&gt; par exemple). Ne vous sentez donc pas obligé de n&#39;utiliser que des composant-fonctions. Utilisez les dès que vous pouvez.&lt;/p&gt;
&lt;h3 id=&quot;les-actions&quot; tabindex=&quot;-1&quot;&gt;Les actions&lt;/h3&gt;
&lt;p&gt;Ok si on récapitule on a donc les vues qui récupèrent leurs données depuis les stores qui eux modifient leurs données selon les informations du dispatcher, la question qui réside est : qui donc fait appel au dispatcher ? La réponse est, bien sûr, les actions.&lt;/p&gt;
&lt;p&gt;C&#39;est dans les actions que la magie opère. C&#39;est elles qui sont à l&#39;origine de tout ce qui peut changer l&#39;état de l&#39;application (ajout/suppression/édition d&#39;un TODO, récupérations des TODOs sur le serveur ...).&lt;br /&gt;
Les actions sont donc les éléments qui vont utiliser le dispatcher pour lancer des évènements que les stores vont interpréter.&lt;/p&gt;
&lt;p&gt;Le code des actions est souvent très simple. Je vais distinguer deux types d&#39;actions :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;les actions qui n&#39;ont d&#39;effets que sur les données locales qui sont souvent synchrones ;&lt;/li&gt;
&lt;li&gt;les actions qui ont un effets sur des données externes (typiquement qui viennent d&#39;une API) qui sont souvent asynchrones.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le premier type d&#39;action est vraiment très simple, il ne fait qu&#39;appeler le dispatcher un point c&#39;est tout.&lt;br /&gt;
Considérons ce scénario d&#39;ajout de TODO :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;l&#39;utilisateur édite son TODO tout frais ;&lt;/li&gt;
&lt;li&gt;quand il a fini, il ajoute son TODO dans la liste ;&lt;/li&gt;
&lt;li&gt;il peut en ajouter plein d&#39;autres ;&lt;/li&gt;
&lt;li&gt;une fois qu&#39;il est content de sa liste de TODOs il peut la sauvegarder sur le serveur.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans ce scénario, il y a les deux type d&#39;actions dont je vous ai parlé.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;addTodo&lt;/code&gt; qui ajoute en local un nouveau TODO ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;saveTodos&lt;/code&gt; qui prend tous les nouveaux TODOs et les sauvegarde via une requête AJAX sur le serveur.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;si on voulait implémenter ces deux actions, ça nous donnerait quelque chose comme ça :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; todoActions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//&quot;Bon allez ça ça part chez les stores qui savent quoi faire de ce truc&quot;&lt;/span&gt;
        dispatcher&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;actionType&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;TODO_ADDED&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; todo
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//my job here is done&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token function-variable function&quot;&gt;saveTodos&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//&quot;OK j&#39;envoie ça au serveur et ensuite je file ça aux stores&lt;/span&gt;
        api
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;saveTodos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;todos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;//OK c&#39;est bon les enfants&lt;/span&gt;
                dispatcher&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token literal-property property&quot;&gt;actionType&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;TODOS_SAVED&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token literal-property property&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;todos
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;//oh merde les gars ça a pas marché&lt;/span&gt;
                dispatcher&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token literal-property property&quot;&gt;actionType&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;TODOS_SAVE_FAILED&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token literal-property property&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; todos
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notez que les évènements dispatchés par les actions décrivent des &lt;strong&gt;choses qui se sont passées&lt;/strong&gt; et pas ce que doit faire l&#39;application par rapport à cette action. Pour illustrer mon propos voila un exemple qu&#39;on pourrait être tenté de faire.&lt;br /&gt;
Prenons le cas où la sauvegarde sur le serveur s&#39;est mal passée (donc on passe dans le &lt;code&gt;catch&lt;/code&gt;), on pourrait avoir envie de dispatcher un &lt;code&gt;&amp;quot;SHOW_NOTIFICATION_TODOS_SAVE_FAIL&amp;quot;&lt;/code&gt;. En faisant ça, on donne à l&#39;action une connaissance de ce que l&#39;application peut faire.&lt;br /&gt;
Or une action ne doit faire que constater ce qu&#39;il se passe et le transmettre.&lt;/p&gt;
&lt;h3 id=&quot;flux-en-r%C3%A9sum%C3%A9&quot; tabindex=&quot;-1&quot;&gt;Flux en résumé&lt;/h3&gt;
&lt;p&gt;Pour résumer un peu voila les idées qui sortent de Flux :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;les stores contiennent toutes les données brutes de l&#39;app ;&lt;/li&gt;
&lt;li&gt;les stores représentent l&#39;état de l&#39;application à l&#39;instant &lt;code&gt;t&lt;/code&gt; et sont donc complètement synchrone ;&lt;/li&gt;
&lt;li&gt;seuls les stores peuvent modifier leurs données ;&lt;/li&gt;
&lt;li&gt;les stores réagissent aux évènements du dispatcher ;&lt;/li&gt;
&lt;li&gt;les stores sont comme un modèle observable mais sans &lt;code&gt;setter&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;les vues écoutent les changements d&#39;un (ou plusieurs) store(s) et se rendent en fonction ;&lt;/li&gt;
&lt;li&gt;une vue qui est reliée à un store est appelée &amp;quot;container&amp;quot; et doit avoir une méthode &lt;code&gt;render&lt;/code&gt; simplissime ;&lt;/li&gt;
&lt;li&gt;le dispatcher est les yeux des stores vis à vis de l&#39;application (il dit au stores tout ce qu&#39;il se passe) ;&lt;/li&gt;
&lt;li&gt;les actions sont là pour appeler le dispatcher et éventuellement des services externes (API, localStorage ...) ;&lt;/li&gt;
&lt;li&gt;pour nommer un évènement que doit dispatcher une action il faut se poser la question « Que vient-il de se passer dans mon application ? » et pas « Que devrait faire mon application face à ça ? »&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et le petit graphique qui résume très bien les interactions entre les composants :&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/facebook/flux/master/docs/img/flux-diagram-white-background.png&quot; alt=&quot;Flux illustrated&quot; /&gt;&lt;/p&gt;
&lt;p&gt;(ps: Pourquoi ce schéma n&#39;apparait que sur le github et nulle part sur la doc alors qu&#39;il résume bien mieux Flux que les schéma qu&#39;on peut trouver &lt;a href=&quot;http://facebook.github.io/flux/docs/overview.html#content&quot;&gt;ici&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;On pourrait représenter une application Flux comme une fonction qui prend en paramètre un état à un instant &lt;code&gt;t&lt;/code&gt; et une action et qui retourne l&#39;état à l&#39;état &lt;code&gt;t+1&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;application(state1, action) =&amp;gt; state2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si on considère que cette fonction est &lt;a href=&quot;https://fr.wikipedia.org/wiki/Fonction_pure&quot;&gt;pure&lt;/a&gt; (qu&#39;elle ne fait que retourner un nouvel état sans rien modifier en mémoire pour faire simple), alors tous les états de cette application sont déterministes (une même action ne pourra pas donner deux résultats différents) et vous pouvez par exemple facilement mettre en oeuvre du &lt;em&gt;undo/redo&lt;/em&gt; (la &lt;a href=&quot;http://rackt.org/redux/docs/recipes/ImplementingUndoHistory.html&quot;&gt;doc de Redux&lt;/a&gt; explique ça très bien).&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Je trouve l&#39;idée qu&#39;a eu Facebook d&#39;implémenter le concept de Flux entièrement dans sa doc très bonne. C&#39;est un peu comme ces articles qui réimplémente une techno populaire (eg. &lt;a href=&quot;http://teropa.info/blog/2013/11/03/make-your-own-angular-part-1-scopes-and-digest.html&quot;&gt;Make your own Angular&lt;/a&gt;) pour l&#39;expliquer. C&#39;est très didactique et permet de vraiment comprendre ce qu&#39;il se passe &lt;em&gt;sous la capuche&lt;/em&gt; (comme disent les américains) des outils qu&#39;on utilise tous les jours (ou presque).&lt;br /&gt;
En revanche je trouve dommage qu&#39;ils n&#39;aient pas plus séparé le concept et l&#39;implémentation dans leur doc. Je reconnais avec le recul que j&#39;aurais pu comprendre ça plus tôt. Je suis surement parti trop vite dans le code sans lire à fond le concept d&#39;abord, mais je pense que je ne suis pas le seul à avoir pris ce chemin.&lt;/p&gt;
&lt;p&gt;Outre ça, le concept de Flux est génial et a vraiment changé ma façon de faire mes applications.&lt;br /&gt;
Alors si je peux vous donner un conseil, c&#39;est trouvez vous une implémentation de Flux qui vous va (ou faites la vous même) et lancez vous :)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Hackerbeach : Organiser mon temps</title>
    <link href="https://blog.atomrc.dev/p/hackerbeach-organisation/"/>
    
    <updated>2015-01-18T00:00:00Z</updated>
    
    <published>2015-01-18T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/hackerbeach-organisation/</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/hhN5FuI.jpg&quot; alt=&quot;Hacking sur la plage&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Comme expliqué dans mon précédent billet (&lt;a href=&quot;https://blog.atomrc.dev/p/hackerbeach-inspect-the-dom/&quot;&gt;Hackerbeach : Coder sur la plage ... en hiver&lt;/a&gt;), je suis parti pour (presque) tout le mois de janvier en Dominique pour y travailler.&lt;br /&gt;
Ce n&#39;est pas vraiment le genre d’environnement de travail auquel je suis habitué et ça serait dommage de ne pas profiter de ce cadre de rêve !&lt;br /&gt;
La question est donc : &lt;strong&gt;comment m&#39;organiser pour, à la fois, profiter à fond de la Dominique tout en bossant efficacement  ?&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;vivre-avec-le-soleil&quot; tabindex=&quot;-1&quot;&gt;Vivre avec le soleil&lt;/h2&gt;
&lt;p&gt;Voila ce que j&#39;ai en tête pour la gestion de mon temps : ne perdre aucune minute de la journée. Pour arriver à ça il va falloir se synchroniser avec le soleil. Ce qui veut dire lever 6h15. Ca me permettra comme ça de pouvoir me libérer une bonne partie de la journée pour visiter, nager, marcher ...&lt;br /&gt;
N&#39;étant pas vraiment un lève tôt, je vous avoue que ça ne me parait pas facile à tenir. Cela dit, après 4 jours de travail ici, je trouve le réveil avec le soleil vraiment facile. Voyons si j&#39;arrive à tenir ce rythme...&lt;/p&gt;
&lt;h2 id=&quot;travailler-n&#39;importe-o%C3%B9&quot; tabindex=&quot;-1&quot;&gt;Travailler n&#39;importe où&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/v823Or9.jpg&quot; alt=&quot;Coding @ home&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Quitte à partir là bas, je compte bien sortir complètement de mes habitudes vélo / boulot / dodo. Et ça, ça commence par ne pas savoir où je vais bosser en me levant.&lt;br /&gt;
Pas de bureaux ici, nous sommes en itinérance complète. L&#39;idée c&#39;est vraiment de &lt;strong&gt;bouger le plus possible&lt;/strong&gt; : voir plein de lieux, essayer de bosser dans des restaurants ou des bars.&lt;br /&gt;
Nous avons une connexion dans notre appartement et, si nous pouvons nous autoriser quelques demi journées de travail à domicile, il est hors de question de faire des journées entières sans bouger !&lt;/p&gt;
&lt;p&gt;Les autres gars de Hackerbeach vivent dans une ville voisine à la notre (à 3 ou 4 km pas plus) aussi, comme bon hacker qui se respecte, on se synchronise via IRC (#hackerbeach sur freenode si vous voulez suivre nos pérégrinations ;)). Aller les rejoindre est une motivation supplémentaire pour sortir de chez nous !&lt;/p&gt;
&lt;h2 id=&quot;travailler-n&#39;importe-quand&quot; tabindex=&quot;-1&quot;&gt;Travailler n&#39;importe quand&lt;/h2&gt;
&lt;p&gt;Si me lever tôt fait partie de mes plans, rien ne dit que je vais nécessairement bosser dès le matin. Rien ne m&#39;empêche de faire un petit bain de mer au réveil puis retour au boulot puis petit restaurant dans la ville, coder quelques heures dans un bar, prendre un pot avec l&#39;équipe, reprendre mon boulot arrivé chez moi.&lt;/p&gt;
&lt;p&gt;Dans une journée j&#39;ai des périodes hyper productives qu&#39;il ne faut surtout pas que je casse et des périodes où je me sens complètement inutile face à mon code. Si je suis dans une phase de créativité intensive, je sais parfaitement que je ne voudrai pas en sortir, quitte à annuler une activité que j&#39;avais prévue. En revanche sur les phases de travail inefficaces une petite heure dans l&#39;eau et c&#39;est reparti !&lt;/p&gt;
&lt;p&gt;J&#39;aime mon boulot et faire avancer DoYouBuzz me tient beaucoup à coeur, aussi je n&#39;ai aucune crainte quant à une éventuelle perte de motivation. Je suis, avant tout, là pour bosser !&lt;/p&gt;
&lt;h2 id=&quot;sortir-de-sa-zone-de-confort&quot; tabindex=&quot;-1&quot;&gt;Sortir de sa zone de confort&lt;/h2&gt;
&lt;p&gt;Je veux dire, déjà cette organisation me change complètement de mon cadre de travail habituel, mais travailler en itinérance pousse encore l&#39;expérience un peu plus loin.&lt;br /&gt;
Pour vous faire un petit topo de mon installation habituelle : Dual screen (15&amp;quot; et 20&amp;quot;), souris + clavier, un bureau et un fauteuil inclinable.&lt;br /&gt;
Evidemment, j&#39;ai du dire au revoir à tout ce confort. Fini le débuggeur sur un écran et le code sur l&#39;autre en plein écran.&lt;br /&gt;
J&#39;ai troqué mon MacBook 15&amp;quot; pour mon portable perso de 13&amp;quot;. Je vais donc devoir m&#39;habituer à splitter un peu mon écran et à réorganiser mon workflow de travail.&lt;/p&gt;
&lt;p&gt;Pour tout vous dire j&#39;avais déjà commencé à travailler comme ça la semaine avant mon départ. Je me suis forcé à ne pas allumer mon deuxième écran et à utiliser mon 13&amp;quot; pour le boulot. Et il s&#39;avère que finalement, mon deuxième écran ne me manque pas tant que ça !&lt;/p&gt;
&lt;p&gt;Pour ce qui est du confort global, c&#39;est pareil, c&#39;est très fluctuant. On va aussi bien pouvoir se trouver dans des fauteuils agréables dans un bar comme sur des simples chaises en bois. Je pense me mettre à travailler un peu debout de temps en temps pour alterner.&lt;/p&gt;
&lt;p&gt;Jusque là, je n&#39;ai pas vraiment expérimenté de gros soucis avec la connexion internet. Elle est clairement beaucoup moins bonne qu&#39;en France mais tout à fait suffisante pour ce que je fais. Il arrive qu&#39;un &lt;code&gt;git pull&lt;/code&gt; avec de nouvelles images puisse prendre un peu de temps, mais le temps de commander un jus de fruit de la passion est c&#39;est bon :)&lt;/p&gt;
&lt;h2 id=&quot;you-are-awesome&quot; tabindex=&quot;-1&quot;&gt;You are awesome&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/SDGqzdB.jpg&quot; alt=&quot;Hackerbeach team&quot; /&gt;
Il y a plusieurs choses qui ont rendue l&#39;aventure possible. Je partais complètement à l&#39;aventure en venant en Dominique. Je ne savais pas vraiment comment j&#39;allais pouvoir bosser là bas. Mais j&#39;ai la chance d&#39;avoir une copine en or qui ne m&#39;a jamais freiné dans mon projet, des potes qui étaient motivés pour partir avec moi et surtout une boite qui m&#39;a entièrement soutenue dans mon aventure.&lt;/p&gt;
&lt;p&gt;Depuis le Reboot DoYouBuzz, on avait déjà commencé à travailler un peu de chez nous et à des heures un peu décalées. Mais il est vrai qu&#39;on préfère, bien souvent, être tous ensembles à déconner que chez nous ou dans un bar. C&#39;est donc la première vraie aventure dans notre histoire d&#39;entreprise libérée et, franchement, je suis vraiment excité à l&#39;idée d&#39;y participer :)
Si l&#39;informatique permet ce genre d&#39;extravagance, je ne pense pas que beaucoup de gens ont l&#39;opportunité de se lancer dans ce genre de projets !&lt;/p&gt;
&lt;p&gt;En bref je remercie tous ceux qui m&#39;ont permis de réaliser ça !&lt;/p&gt;
&lt;p&gt;Je vous fait un petit débrief de toute cette aventure une fois rentré en France :)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Hackerbeach : Coder sur la plage ... en hiver</title>
    <link href="https://blog.atomrc.dev/p/hackerbeach-inspect-the-dom/"/>
    
    <updated>2015-01-14T00:00:00Z</updated>
    
    <published>2015-01-14T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/hackerbeach-inspect-the-dom/</id>
    <content type="html">&lt;p&gt;Nous sommes en Octobre, j&#39;avais déjà entendu parler de Hackerbeach par &lt;a href=&quot;https://twitter.com/XioNoXfr&quot;&gt;@XioNoXfr&lt;/a&gt; (qui avait déjà fait l&#39;édition 2014 et qui était motivé pour la 2015) et là je tombe sur ce tweet :&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;fr&quot;&gt;&lt;p&gt;It&amp;#39;s official now: Hacker Beach is going to Dominica!&lt;/p&gt;&amp;mdash; Hacker Beach (@hackerbeach) &lt;a href=&quot;https://twitter.com/hackerbeach/status/520021673735884800&quot;&gt;9 Octobre 2014&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;Ni une ni deux je parle un peu de ça autour de moi, et notamment à &lt;a href=&quot;https://twitter.com/gildasq&quot;&gt;@GildasQ&lt;/a&gt; qui n&#39;hésite pas une seule seconde et me dit : Banco on y va !&lt;/p&gt;
&lt;p&gt;Bref nous voilà donc tous les trois partis dans les Caraïbes pour l&#39;édition 2015 de Hackerbeach.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/LnlgtlOl.jpg&quot; alt=&quot;Ready to hack !&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Cette démarche s&#39;inscrivait aussi parfaitement dans le reboot de DoYouBuzz qu&#39;on a fait récemment (cf. &lt;a href=&quot;https://medium.com/doyoubuzz-open/doyoubuzz-reboot-fr-80dc9ea32a38&quot;&gt;DoYouBuzz Reboot&lt;/a&gt;). Aussi, quand j&#39;ai parlé aux gars de l&#39;idée de partir là bas, ils trouvaient le concept génial. C&#39;est un bon moyen de mettre à l&#39;épreuve notre capacité à travailler en remote et à valider notre modèle d&#39;entreprise libérée :)&lt;/p&gt;
&lt;p&gt;Cet article a pour but de présenter brièvement l&#39;idée derrière Hackerbeach et mes impressions sur l&#39;île jusque là. Je ferai, par la suite, un article qui parlera plus de mon organisation personnelle vis à vis de mon travail / rythme de vie.&lt;/p&gt;
&lt;h2 id=&quot;hackerbeach-qu&#39;est-ce-que-%C3%A7a-%3F&quot; tabindex=&quot;-1&quot;&gt;Hackerbeach qu&#39;est ce que ça ?&lt;/h2&gt;
&lt;h3 id=&quot;l&#39;initiative&quot; tabindex=&quot;-1&quot;&gt;L&#39;initiative&lt;/h3&gt;
&lt;p&gt;Hackerbeach c&#39;est une bande de potes qui se sont dit, il y a trois ans : &amp;quot;bordel, &lt;strong&gt;pourquoi on s&#39;oblige à bosser en Europe en hiver par 0°C alors qu&#39;on pourrait bosser en sirotant des cocktails sur des plages paradisiaques ?&lt;/strong&gt;&amp;quot;.&lt;br /&gt;
Quand on sais que pour bosser on a juste besoin d&#39;un portable et d&#39;une connexion internet décente, la question est tout à fait légitime !&lt;br /&gt;
Sur ce principe là, ils se sont mis en quête d&#39;endroits rêvés pour exercer leur art.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;L&#39;édition 2013 était à Phu Quoc (une île au large du Vietnam) ;&lt;/li&gt;
&lt;li&gt;L&#39;édition 2014 à Lamu (une île au Kenya) ;&lt;/li&gt;
&lt;li&gt;et cette année : en Dominique.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ils ont rendu l&#39;évènement public et chacun est libre de venir les rejoindre pour passer du bon temps entre hackers tout en ayant une vraie ambiance de taf.&lt;br /&gt;
Après trois jours de boulot avec eux, je peux vous dire que ces mecs sont des bosseurs. Dès qu&#39;ils ont 5 min et une connexion à proximité, ils dégainent leurs ordi pour descendre du bug ou juste avancer un petit bout de code en suspens.&lt;/p&gt;
&lt;h3 id=&quot;l&#39;%C3%A9dition-2015&quot; tabindex=&quot;-1&quot;&gt;L&#39;édition 2015&lt;/h3&gt;
&lt;p&gt;Cette année on est 11 sur l&#39;île (mais je n&#39;ai pas encore eu l’occasion de les rencontrer tous). C&#39;est génial de voir que pas mal de monde s&#39;est motivé pour venir. Il y a des gens qui viennent d&#39;Allemagne, de France et de République Tchèque.&lt;/p&gt;
&lt;p&gt;Si l&#39;idée principale est, bien sûr, de coder, il est hors de question de chômer en dehors des heures de boulot. On s&#39;est notamment inscrit pour passer notre premier niveau de plongée :)&lt;br /&gt;
Pas besoin de préciser que randos, baignades, visites et autres activités touristiques en tout genre sont au programme ;)&lt;/p&gt;
&lt;h2 id=&quot;la-dominique&quot; tabindex=&quot;-1&quot;&gt;La Dominique&lt;/h2&gt;
&lt;p&gt;Ca fait tout juste 5 jours que je suis arrivé en Dominique et s&#39;il y a bien une chose que je peux dire, c&#39;est que les gens sont &lt;strong&gt;vraiment gentils&lt;/strong&gt;.&lt;br /&gt;
Autant dans la capitale, Roseau, les locaux savent bien repérer les touristes et font tout pour leur faire cracher quelques dollars, autant dans notre coin, Portsmouth, les gens sont juste adorables.&lt;br /&gt;
Notre hôte, par exemple, nous avait commandé des pizzas un peu avant qu&#39;on arrive car il savait qu&#39;on aurait faim ! Dans la rue, tout le monde vous dit bonjour et en quelques jours, on a déjà l&#39;impression de connaitre tout le quartier. En bref, on se sent chez soi très rapidement.&lt;/p&gt;
&lt;p&gt;Un autre point avec la Dominique, il ne faut jamais être trop pressé. Globalement les gens n&#39;ont pas l&#39;air de se mettre une quelconque pression pour quoi que ce soit. Exemple amusant : on avait besoin d&#39;acheter une bouteille de gaz dans un supermarché, seulement il pleuvait ce jour là. Le gars qui tenais la caisse n&#39;avait pas vraiment envie de se mouiller, qu&#39;est-ce qu&#39;il a fait alors ? Il a patiemment attendu que la pluie s&#39;arrête avant d&#39;aller chercher la bouteille. Ca a bien duré 10 minutes et il y avait des clients derrière qui faisaient la queue mais personne n&#39;avait l&#39;air de vouloir bouger pour faire avancer la situation.&lt;/p&gt;
&lt;h2 id=&quot;let&#39;s-hack&quot; tabindex=&quot;-1&quot;&gt;Let&#39;s Hack&lt;/h2&gt;
&lt;p&gt;Pour l&#39;instant nous n&#39;avons que trois jours de hack au compteur, donc pas vraiment de retour d&#39;expérience significatif à partager. Mais je compte faire un autre article qui s&#39;orientera plus sur mon organisation (boulot, activités, rythme de vie ...). Je ferai sûrement ça à la fin de ma première semaine de boulot remote.&lt;/p&gt;
&lt;p&gt;So stay tuned :)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/ro8VjmS.jpg&quot; alt=&quot;La vue de l&#39;un de nos point de hack&quot; /&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Regex : tips and tricks</title>
    <link href="https://blog.atomrc.dev/p/regex/"/>
    
    <updated>2014-09-05T00:00:00Z</updated>
    
    <published>2014-09-05T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/regex/</id>
    <content type="html">&lt;p&gt;Allez comme je sais que vous adorez les Expressions Régulières, voila quelques tricks sympas :).&lt;br /&gt;
&lt;strong&gt;Attention, ces techniques ne sont pas disponibles sur tous les moteurs d&#39;expressions régulières&lt;/strong&gt;. Pour savoir si les astuces dont je parle dans cet article sont disponibles dans votre langage préféré, je vous invite à consulter ce tableau &lt;a href=&quot;http://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines&quot;&gt;Comparison of Regular Expression engines&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;la-r%C3%A9p%C3%A9tition-%22ungreedy%22&quot; tabindex=&quot;-1&quot;&gt;la répétition &amp;quot;ungreedy&amp;quot;&lt;/h2&gt;
&lt;p&gt;Par défault la répétition va essayer de matcher le plus de caractères possibles. Par exemple (en JavaScript) :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; reg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&amp;lt;.*&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    str &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;a piece of html: &amp;lt;html&gt;&amp;lt;head&gt;&amp;lt;/head&gt;&amp;lt;/html&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;str&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//print : &quot;&amp;lt;html&gt;&amp;lt;head&gt;&amp;lt;/head&gt;&amp;lt;/html&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mais souvent vous voulez limiter la portée de votre répétition pour ne matcher que &lt;strong&gt;la plus petite chaine&lt;/strong&gt;. Dans ce cas là, on va utiliser la répétition &amp;quot;ungreedy&amp;quot; en utilisant le symbole &lt;code&gt;?&lt;/code&gt; après la répétition. Ce qui nous donne donc :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; reg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&amp;lt;.*?&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    str &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;a piece of html: &amp;lt;html&gt;&amp;lt;head&gt;&amp;lt;/head&gt;&amp;lt;/html&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;str&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//print : &quot;&amp;lt;html&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Une autre solution pour arriver à ce résultat serait :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; reg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&amp;lt;[^&gt;]*&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Moins sexy tout de même :)&lt;/p&gt;
&lt;p&gt;Vous pouvez utiliser cette astuce avec tous les types de répétitions (le &lt;code&gt;*&lt;/code&gt;, le &lt;code&gt;+&lt;/code&gt;, les &lt;code&gt;{.,.}&lt;/code&gt; et le &lt;code&gt;?&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id=&quot;le-lookahead&quot; tabindex=&quot;-1&quot;&gt;le lookahead&lt;/h2&gt;
&lt;p&gt;Parfois, avez besoin de faire des vérifications dans votre chaine de caractères, sans pour autant vous déplacer dedans.&lt;br /&gt;
Exemple typique, vérifier que différentes conditions sont présentes dans la chaine, sans savoir dans quel ordre elles seront.&lt;br /&gt;
Admettons que vous voulez trouver toutes les phrases ou apparaissent à la fois &lt;code&gt;Felix&lt;/code&gt; et &lt;code&gt;stratosphere&lt;/code&gt; dans la chaîne suivante :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;I heard Felix is going to jump from the stratosphere.  
I know he&#39;s going to do it.  
Felix is the best.  
The stratosphere isn&#39;t far enough for Felix.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On va alors utiliser un lookahead pour vérifier que les mots &lt;code&gt;Felix&lt;/code&gt; et  &lt;code&gt;stratosphere&lt;/code&gt; sont présents dans la chaine sans faire attention à leur position. Pour cela il serait idéal &lt;strong&gt;de lire la chaine mais sans ce déplacer dedans&lt;/strong&gt; ! C&#39;est justement le but du lookahead qui permet de simplement regarder sans faire avancer le pointeur de lecture de votre regex.&lt;/p&gt;
&lt;p&gt;L&#39;idée est donc d&#39;aller regarder si &lt;code&gt;stratosphere&lt;/code&gt; est dans la chaine, puis si &lt;code&gt;Felix&lt;/code&gt; est dans cette même chaine (en partant toujours du début) et si ces deux conditions sont réunies alors commencer le matching.&lt;/p&gt;
&lt;p&gt;Le lookahead (positif) s&#39;écrit &lt;code&gt;(?=regex)&lt;/code&gt; (il existe également le lookup négatif qui cherche quelque chose qui ne doit pas exister qui s&#39;écrit &lt;code&gt;(?!regex)&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;Voila la solution au problème précédent (toujours en JavaScript :)) :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; reg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;(?=.*stratosphere)(?=.*Felix).*?&#92;.&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    str &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;I heard Felix is going to jump from the stratosphere.&#92;n I know he&#39;s going to do it.&#92;n Felix is the best.&#92;n The stratosphere isn&#39;t far enough for Felix.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;str&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//[ &quot;I heard Felix is going to jump from the stratosphere.&quot;, &quot; The stratosphere isn&#39;t far enough for Felix.&quot; ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Une solution possible sans utiliser les lookahead serait :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; reg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;.*(Felix.*stratosphere|stratosphere.*Felix).*&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vous saisissez l&#39;idée : on vérifie que on trouve :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;soit &lt;code&gt;Felix&lt;/code&gt; puis &lt;code&gt;stratosphere&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;soit &lt;code&gt;stratosphere&lt;/code&gt; puis &lt;code&gt;Felix&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Encore une fois, un petit manque de sexy :)&lt;/p&gt;
&lt;p&gt;Un bon use case de cette technique serait par exemple de &lt;strong&gt;vérifier qu&#39;un password dispose d&#39;au moins une majuscule et d&#39;un digit&lt;/strong&gt;. (Je vous laisse ça en exercice ;))&lt;/p&gt;
&lt;p&gt;Voila n&#39;hésitez pas à laisser d&#39;autres techniques pratiques que vous utilisez avec nos chères amies les &lt;code&gt;regex&lt;/code&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Penser comme Vim</title>
    <link href="https://blog.atomrc.dev/p/penser-comme-vim/"/>
    
    <updated>2014-08-05T00:00:00Z</updated>
    
    <published>2014-08-05T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/penser-comme-vim/</id>
    <content type="html">&lt;p&gt;Ca fait maintenant 3 ans que je n&#39;utilise plus que Vim comme éditeur de textes. Ca fait aussi longtemps que je pensais écrire un article dessus et, allez, aujourd&#39;hui, je me lance :)&lt;/p&gt;
&lt;h2 id=&quot;pourquoi-j&#39;adore-vim&quot; tabindex=&quot;-1&quot;&gt;Pourquoi j&#39;adore Vim&lt;/h2&gt;
&lt;p&gt;Bon soyons franc, je pense que le premier contact avec Vim ça se passe souvent comme ça :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Outch ! Qu&#39;est ce que je dois faire de ça moi ?&amp;quot; ;&lt;/li&gt;
&lt;li&gt;&amp;quot;Oh bordel, on ne peut pas éditer ! si j&#39;avais voulu lancer &lt;code&gt;less&lt;/code&gt; j&#39;aurais tapé &lt;code&gt;less&lt;/code&gt; !&amp;quot; ;&lt;/li&gt;
&lt;li&gt;et après quelques minutes de rage contenue, le fameux &amp;quot;Putain comment on quitte ce bousin !&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/y0TwyKxl.png&quot; alt=&quot;nothing to do here&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Après cette expérience, il y a deux types de personnes, les &lt;code&gt;apt-get purge vim&lt;/code&gt; et ceux qui se disent &amp;quot;ça ressemble à un défi pour moi !&amp;quot; (et qui ont un peu de temps devant eux :) ).&lt;/p&gt;
&lt;p&gt;Admettons le, il faut être un peu maso pour relancer la commande &lt;code&gt;vim&lt;/code&gt; :). Personnellement j&#39;adore les défis, je me suis donc rangé dans la seconde catégorie de personnes.&lt;/p&gt;
&lt;p&gt;Contrairement à beaucoup d&#39;IDE qui vous donnent accès à toutes les commandes possibles à portée de souris, Vim vous parachute directement à poil en pleine jungle. Mais c&#39;est là que vous allez progresser le plus. Vous allez devoir beaucoup mobiliser votre mémoire et faire un gros effort de compréhension/adaptation avant de pouvoir vous faire plaisir avec Vim.&lt;/p&gt;
&lt;p&gt;Quand vous commencerez à maîtriser la bête, vous ne vous direz pas que vous avez trouvé un éditeur qui défonce, mais plutôt que vous êtes un demi-dieux de l&#39;édition de code. Après tout c&#39;est peut-être simplement ça que j&#39;aime dans Vim, il flatte tout simplement mon égo !&lt;/p&gt;
&lt;h2 id=&quot;gardons-les-pieds-sur-terre&quot; tabindex=&quot;-1&quot;&gt;Gardons les pieds sur terre&lt;/h2&gt;
&lt;p&gt;Voila quelques arguments un peu plus formels en faveur de Vim :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Il est quasi universel (installé par défaut sur la majorité des systèmes UNIX) ;&lt;/li&gt;
&lt;li&gt;Il est parfait pour l&#39;édition sur un serveur distant ;&lt;/li&gt;
&lt;li&gt;Il consomme très peu de ressources ;&lt;/li&gt;
&lt;li&gt;Il est facilement extensible ;&lt;/li&gt;
&lt;li&gt;Il est très facilement personnalisable ;&lt;/li&gt;
&lt;li&gt;Il vous aboli complètement du dictat de la souris ;&lt;/li&gt;
&lt;li&gt;Pas d&#39;interface graphique qui vous distrait, simplement votre code (une belle occasion de &lt;a href=&quot;https://blog.atomrc.dev/p/faire-la-part-belle-au-code/&quot;&gt;faire la part belle au code&lt;/a&gt;) ;&lt;/li&gt;
&lt;li&gt;Vous pouvez exécuter n&#39;importe quelle commande &lt;code&gt;bash&lt;/code&gt; directement depuis Vim.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vous remarquerez que je ne parle pas ici d&#39;amélioration de votre productivité (comme certains peuvent l&#39;affirmer) parce que je ne pense vraiment pas que Vim y change grand chose. Certes vous gagnez un peu de temps en vous libérant de votre souris. Cependant, face aux temps de compilation / rechargements de page / temps de réflexion / pauses café ... Je ne pense vraiment pas que ça soit significatif.&lt;/p&gt;
&lt;h2 id=&quot;comprendre-vim&quot; tabindex=&quot;-1&quot;&gt;Comprendre Vim&lt;/h2&gt;
&lt;p&gt;Il y a deux choses à avoir en tête quand vous utilisez Vim : il y a &lt;strong&gt;plusieurs états&lt;/strong&gt; et &lt;strong&gt;les commandes sont une suite d&#39;instructions atomiques&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;les-%C3%A9tats&quot; tabindex=&quot;-1&quot;&gt;Les états&lt;/h3&gt;
&lt;p&gt;Dans Vim, il y a 3 états distincts : l&#39;&lt;strong&gt;édition&lt;/strong&gt; (le mode &lt;code&gt;normal&lt;/code&gt;), l&#39;&lt;strong&gt;insertion&lt;/strong&gt; (le mode &lt;code&gt;insert&lt;/code&gt;) et le &lt;strong&gt;visuel&lt;/strong&gt; (le mode &lt;code&gt;visual&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Insert&lt;/code&gt;. Le mode insertion, est le plus facile à comprendre. C&#39;est en fait le mode par défaut de la majorité des éditeurs de textes. En bref, quand vous appuyez sur une touche, le caractère sur cette touche vient s&#39;imprimer dans votre éditeur. Oui c&#39;est ce qu&#39;on attend d&#39;un éditeur de texte et &lt;strong&gt;non ça n&#39;est pas le mode par défaut&lt;/strong&gt; ! Pour accéder à ce mode, tapez &lt;code&gt;i&lt;/code&gt; (entre autres comme &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;o&lt;/code&gt; ...) quand vous êtes en mode &lt;code&gt;normal&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Visual&lt;/code&gt;. Le mode visuel va vous permettre de sélectionner du texte (à l&#39;instar de la sélection via la souris) pour en faire ce que vous voulez (le copier, le supprimer, l&#39;encadrer avec des balises ...). Pour mettre Vim en mode &lt;code&gt;visual&lt;/code&gt; il vous suffit de taper &lt;code&gt;v&lt;/code&gt; quand vous êtes en mode &lt;code&gt;normal&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Normal&lt;/code&gt;. Le mode normal est le mode qui est de loin le plus intéressant de Vim, et c&#39;est celui par défaut quand vous lancez Vim. C&#39;est avec ce mode que vous allez pouvoir titiller la bête et vous amuser avec les commandes. Il ne faut plus voir votre clavier comme un ensemble de caractères, mais plutôt comme &lt;strong&gt;un ensemble de raccourcis vers des commandes de modification de texte&lt;/strong&gt;. Pour l&#39;activer appuyez simplement sur la touche &lt;code&gt;esc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;C&#39;est intéressant de constater la séparation de ses trois modes. Alors que la plupart des éditeurs n&#39;ont qu&#39;un seul mode (un mélange des trois de Vim), Vim se laisse une place toute particulière pour les commandes d&#39;édition. En &lt;code&gt;normal&lt;/code&gt; tout le clavier est entièrement disponible pour accueillir les commandes, je vous laisse imaginer le nombre de possibilités à portées d&#39;un seul caractère ;)&lt;/p&gt;
&lt;p&gt;Du fait d&#39;avoir trois modes différents, vous devrez faire une petite gymnastique mentale pour savoir comment reconnaitre en quel mode vous êtes (par exemple le curseur change de style en fonction du mode) ou mieux vous rappeler en quel mode vous avez laissé votre Vim :). Assez souvent, ce sont surtout des automatismes qui se mettent en place tout seul. Par exemple j&#39;ai pris le réflexe de toujours revenir en mode &lt;code&gt;normal&lt;/code&gt; dès que j&#39;ai finir de taper ce que j&#39;avais en tête.&lt;/p&gt;
&lt;h3 id=&quot;les-commandes&quot; tabindex=&quot;-1&quot;&gt;Les commandes&lt;/h3&gt;
&lt;p&gt;Vous l&#39;aurez compris, pour accéder à la toute puissance de Vim (les commandes), il faudra vous mettre en mode &lt;code&gt;normal&lt;/code&gt;. La clé pour comprendre la suite des opérations est de se rentrer en tête que Vim ne fait que des traitements très atomiques sur votre texte. C&#39;est à vous de combiner les opérations atomiques pour faire ce que vous voulez sur votre texte.&lt;/p&gt;
&lt;p&gt;Pour ça vous avez trois types de commandes vim :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;les &lt;strong&gt;déplacements&lt;/strong&gt; ;&lt;/li&gt;
&lt;li&gt;les &lt;strong&gt;actions&lt;/strong&gt; ;&lt;/li&gt;
&lt;li&gt;les &lt;strong&gt;opérateurs&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&#39;idée est donc d&#39;aller combiner les différentes commandes pour faire ce que vous voulez. A part quelques cas particuliers, les commandes sont assez simples à retenir puisque, bien souvent, il s&#39;agit de la première lettre du mot en anglais qui défini l&#39;action faite par la commande. Quelques exemples :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;d&lt;/code&gt; (pour &lt;code&gt;delete&lt;/code&gt;) va supprimer du texte ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r&lt;/code&gt; (pour &lt;code&gt;replace&lt;/code&gt;) va en remplacer ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;i&lt;/code&gt; (pour &lt;code&gt;insert&lt;/code&gt;) va se mettre en mode normal en gardant la position du curseur ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a&lt;/code&gt; (pour &lt;code&gt;after&lt;/code&gt;) va se mettre en insertion en déplaçant le curseur sur le caractère après sa position actuelle ;&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A partir de ça il ne vous reste plus qu&#39;a faire des phrases pour expliquer à Vim ce que vous voulez faire. &lt;code&gt;dt.&lt;/code&gt; (pour &lt;code&gt;delete till .&lt;/code&gt;) va supprimer le texte entre votre curseur et le prochain caractère &lt;code&gt;.&lt;/code&gt;, &lt;code&gt;ci&amp;quot;&lt;/code&gt; (pour &lt;code&gt;change inside &amp;quot;&lt;/code&gt;) va supprimer ce qu&#39;il y a entre les &lt;code&gt;&amp;quot;&lt;/code&gt; et vous mettre en mode insertion à l&#39;intérieur.&lt;/p&gt;
&lt;p&gt;Libre à vous de répéter plusieurs fois une commande en ajoutant un nombre dans votre phrase :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;d2w&lt;/code&gt; (&lt;code&gt;delete 2 words&lt;/code&gt;) va supprimer les deux prochains mots ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;y2{&lt;/code&gt; (pour &lt;code&gt;yanc 2 paragraph&lt;/code&gt;) copie les deux prochain paragraphes ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2p&lt;/code&gt; (pour &lt;code&gt;two pastes&lt;/code&gt;) colle deux fois le contenu du presse papier.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Normalement, si vous avez bien compris ça, vous allez être à même de déchiffrer la fameuse cheat sheet de Vim.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/wjPmWGvl.gif&quot; alt=&quot;Vim cheat-sheet&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Je vous conseille de la garder près de vous surtout au début.&lt;/p&gt;
&lt;h2 id=&quot;les-mots-de-la-fin&quot; tabindex=&quot;-1&quot;&gt;Les mots de la fin&lt;/h2&gt;
&lt;p&gt;La philosophie de Vim est de vous économiser un maximum de déplacement de mains sur votre clavier. Aussi, même si c&#39;est un peu dur au début, essayer de vous forcer à utiliser &lt;code&gt;h&lt;/code&gt;, &lt;code&gt;j&lt;/code&gt;, &lt;code&gt;k&lt;/code&gt; et &lt;code&gt;l&lt;/code&gt; (en mode &lt;code&gt;normal&lt;/code&gt;) pour vous déplacer caractère par caractère au lieux d&#39;utiliser les flèches (ou pire la souris). Avec l&#39;habitude vous aurez même tendance à ne vous déplacer que par recherche (avec &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;?&lt;/code&gt;, &lt;code&gt;t&lt;/code&gt;, &lt;code&gt;T&lt;/code&gt;, &lt;code&gt;f&lt;/code&gt; et &lt;code&gt;F&lt;/code&gt; article à lire absolument sur le sujet &lt;a href=&quot;http://benmccormick.org/2014/08/04/learning-vim-in-2014-search/&quot;&gt;Learning Vim in 2014: Search&lt;/a&gt;) ou par positions spéciales comme &lt;code&gt;$&lt;/code&gt; (fin de la ligne) ou &lt;code&gt;^&lt;/code&gt; (début de la ligne). C&#39;est aussi l’occasion d&#39;apprendre à bien placer et à bien utiliser tous ses doigts sur le clavier ;)&lt;/p&gt;
&lt;p&gt;Vous verrez ensuite que beaucoup de services utilisent ce système de déplacement et de commandes mappées sur des touches (j&#39;ai en tête &lt;a href=&quot;http://github.com/&quot;&gt;Github&lt;/a&gt;, &lt;a href=&quot;http://gmail.com/&quot;&gt;Gmail&lt;/a&gt; et beaucoup de services Google d&#39;ailleurs, &lt;a href=&quot;https://bitbucket.org/&quot;&gt;Bitbucket&lt;/a&gt;, &lt;a href=&quot;http://jira.com/&quot;&gt;Jira&lt;/a&gt;, &lt;a href=&quot;http://feedly.com/&quot;&gt;Feedly&lt;/a&gt;. Essayez donc d&#39;appuyer sur &lt;code&gt;?&lt;/code&gt; sur ces sites ;) ). Une fois que vous vous serez bien adapté à Vim, vous n&#39;aurez pas de mal à utiliser les raccourcis de ses services.&lt;/p&gt;
&lt;p&gt;Même si Vim est très fonctionnel de base sans aucune configuration, il est important que vous personnalisiez votre environnement (coloration syntaxique, espace vs tabs ...). Pour ça je vous invite à aller voir &lt;a href=&quot;https://github.com/atomrc/dotfiles/blob/master/vim/.vimrc&quot;&gt;ma configuration&lt;/a&gt; pour la mettre à votre sauce.&lt;/p&gt;
&lt;p&gt;Un petit conseil, pour vous y mettre doucement est de commencer par le tutoriel proposé par Vim directement. Pour ça tapez simplement &lt;code&gt;vimtutor&lt;/code&gt; dans votre terminal et laissez vous guider ;)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Faire la part belle au code</title>
    <link href="https://blog.atomrc.dev/p/faire-la-part-belle-au-code/"/>
    
    <updated>2013-10-08T00:00:00Z</updated>
    
    <published>2013-10-08T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/faire-la-part-belle-au-code/</id>
    <content type="html">&lt;p&gt;Mon expérience de développeur est relativement jeune (cela fait maintenant 1 an que j&#39;ai commencé mon premier job chez &lt;a href=&quot;http://doyoubuzz.com/&quot;&gt;DoYouBuzz&lt;/a&gt;), mais s&#39;il y a bien quelque chose que j&#39;ai compris sur le code c&#39;est qu&#39;il est, avant tout, personnel.
Grammaires de langage, conventions, algorithmes, snippets de code et linters sont autant d&#39;outils qui cadrent l&#39;écriture de code, et pourtant il reste une &lt;strong&gt;infinité de liberté&lt;/strong&gt;.
Vous pouvez suivre toutes les conventions de codage que vous voulez, il y aura toujours une petite partie de vous dans votre code.
Mais s&#39;il vous appartient, vous en êtes aussi responsable. Il est de votre devoir de développeur de &lt;strong&gt;prendre soin de votre code&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;L&#39;écriture de code c&#39;est de la poésie&lt;/strong&gt;. Vous avez à votre disposition toutes les figures de style que vous voulez pour &lt;strong&gt;transformer une partition de caractères ASCII ennuyeux en poème&lt;/strong&gt;. Vous pouvez tout à fait vous laisser aller à quelques &lt;a href=&quot;http://blog.marcomonteiro.net/post/35697947390/yoda-conditions&quot;&gt;Yoda Conditions&lt;/a&gt;. Vous êtes libres de concentrer votre code ou au contraire opter pour la légèreté et les retours à la lignes. Vous serez peut-être un amateur des return et en placerez dès que vous pouvez dans vos fonctions. Inversement vous vous lancerez dans une mise en abîme de if imbriqués. C&#39;est à vous de choisir si vous préférez une approche &lt;a href=&quot;http://fr.wikipedia.org/wiki/Programmation_fonctionnelle&quot;&gt;fonctionnelle&lt;/a&gt; ou plutôt &lt;a href=&quot;http://fr.wikipedia.org/wiki/Programmation_imperative&quot;&gt;impérative&lt;/a&gt;. Dans tous les cas &lt;strong&gt;votre code vous appartient&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Construisez vous votre environnement de création&lt;/strong&gt;. Ce n&#39;est pas avec l&#39;application que vous créez mais bien avec votre éditeur de texte que vous passerez le plus clair de votre temps. Tout comme le poète a besoin d&#39;un cadre stimulant et d&#39;une plume avec laquelle il est à l&#39;aise, vous vous devez de trouver l&#39;éditeur qui vous convient le mieux. Certain préféreront un Eclipse bien configuré avec toutes les fonctionnalités dont ils ont besoin à portée de souris. D&#39;autres préféreront l&#39;élégance du code pur et le confort du clavier et choisiront plutôt un Vim avec quelques plugins et toutes les commandes utiles en tête.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Soyez conscient&lt;/strong&gt;. Vous êtes libres de faire ce que vous voulez de votre code, cependant, vous devez impérativement être conscient des conséquences de vos choix. Apprenez à fond les langages que vous manipulez et adaptez votre style au langage et à la plateforme pour laquelle vous écrivez. Sachez, par exemple, qu&#39;une approche fonctionnelle va être globalement plus couteuse en mémoire qu&#39;une approche impérative. Comprenez que vos collègues n&#39;apprécieront pas forcement de relire des yoda conditions. Votre code peut être original, mais jamais au détriments des performances ou de la relecture.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;N&#39;ayez pas peur de la suppression&lt;/strong&gt;. Supprimer des bouts de code est peut-être le sentiment le plus grisant du code. Supprimer du code, ça peut vouloir dire deux choses : soit la fonctionnalité est enlevée, soit vous avez réussi à factoriser la fonctionnalité en question. Dans les deux cas votre application ne s&#39;en portera que mieux et votre code également. Dans le code, et tout particulièrement pour le web, moins de code veut dire un temps de chargement plus faible et moins de bugs potentiels.
Je pense vraiment qu&#39;une des choses qui qualifient un bon développeur et de pouvoir faire autant avec moins. Ne soyez plus ce collégien qui essaye absolument de remplir ses 5 pages de dissertation parce que la prof a dit &amp;quot;entre 5 et 10 pages&amp;quot; (oui, j&#39;ai fait ça !).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Relisez et remaniez&lt;/strong&gt;. Ne laissez jamais un bout de code dormir trop longtemps. Personne ne fait les choses parfaitement du premier coup. allez relire régulièrement du code que vous avez fait hier, la semaine dernière, le mois dernier ou encore l&#39;année dernière. Vous pourrez être surpris par ce que vous lirez. Vous vous direz surement que vous avez bien changé depuis. C&#39;est bon signe : c&#39;est que vous progressez :)
N&#39;hésitez pas, à ce moment là, à réécrire ce qui vous choque.
Dans mes projets persos, qui n&#39;ont donc pas de deadlines (ce blog par exemple), je prends souvent le temps de refaire une fonctionnalité de A à Z. Assez régulièrement je me rends compte que je pouvais la faire bien plus simplement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Réfléchissez&lt;/strong&gt;. On sais tous qu&#39;il ne faut pas attaquer un problème de plein fouet sans y avoir réfléchi un minimum. C&#39;est très vrai, mais il y a une réflexion dont on parle moins : la réflexion à posteriori. Quand vous pensez le code avant de l&#39;attaquer, vous savez ce qu&#39;il doit faire mais pas ce qu&#39;il va faire. Une fois le développement fini, vous avez précisément en tête les mécanismes de votre code ainsi que les détails de la fonctionnalité. C&#39;est à ce moment que vous pourrez opérer suppression de code et remaniement.
J&#39;ai souvent entendu dire que lorsqu&#39;on créé un bout de code, il ne faut pas penser optimisation dans un premier temps. Il est préférable de coder de façon (presque) naïve une première fois, puis ensuite d&#39;identifier les bouts de code qui peuvent être factorisés/supprimés. Faire le contraire risque de vous embrouiller l&#39;esprit au point de ne plus avoir en tête la fonctionnalité que vous développez. Les tests sont également là pour vous aider à préciser votre idée et surtout à valider vos futurs réécritures, utilisez les !&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Soyez curieux&lt;/strong&gt;. Une dernière chose, et pas des moindre : la curiosité. Quand quelque chose vous intrigue, que vous vous demandez comment ça marche, voyez y une opportunité de creusez plus loin, de progresser. L&#39;Open Source (sous la forme de &lt;a href=&quot;http://github.com/&quot;&gt;github&lt;/a&gt; par exemple) est une source d&#39;informations et d&#39;inspirations infinie ! Allez voir, par exemple, comment &lt;a href=&quot;http://github.com/jquery/jquery&quot;&gt;jQuery&lt;/a&gt; a réussi à abstraire et unifier les apis du DOM des différents navigateurs. C&#39;est en lisant le code d&#39;autres personnes que vous trouverez de l&#39;inspiration et des façon de faire complétement différentes des vôtres. Apprenez d&#39;autres langages de programmation qui n&#39;ont rien à voir avec ce que vous faites, ça vous &lt;a href=&quot;http://wekeroad.com/2013/05/13/knowing-more-programming-languages-will-make-you-smarter&quot;&gt;rendra plus intelligent&lt;/a&gt;. A mon avis, &lt;strong&gt;la curiosité est ce qui fait/fera d&#39;un bon développeur, un excellent développeur&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Les quelques points que je traites dans cet article sont des réflexions qui me sont propres et qui me sont chères. Je n&#39;ai aucune prétention de diffuser une quelconque doctrine du bon petit développeur, je n&#39;ai clairement pas assez d&#39;expérience pour pouvoir en faire autant. Cependant si un seul de ces points peut vous offrir une piste de réflexion si minime soit elle, alors ma mission est réussie.&lt;/p&gt;
&lt;p&gt;Alors prenez bien soin de votre code et n&#39;hésitez pas à réagir ;)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Javascript : Single-threaded et asynchrone</title>
    <link href="https://blog.atomrc.dev/p/javascript-single-threaded-et-asynchrone/"/>
    
    <updated>2013-06-01T00:00:00Z</updated>
    
    <published>2013-06-01T00:00:00Z</published>
    <id>https://blog.atomrc.dev/p/javascript-single-threaded-et-asynchrone/</id>
    <content type="html">&lt;p&gt;Javascript est single-threaded, c&#39;est quelque chose qui est rentré dans la tête de la plupart des développeurs front-end. Cependant ce à quoi on ne réfléchit pas assez c&#39;est : comment est-il possible d&#39;être à la fois single-threaded et de gérer du code asynchrone.&lt;/p&gt;
&lt;h2 id=&quot;les-cons%C3%A9quences-du-thread-unique&quot; tabindex=&quot;-1&quot;&gt;Les conséquences du thread unique&lt;/h2&gt;
&lt;p&gt;Bon c&#39;est bien beau de savoir que Javascript ne dispose que d&#39;un seul thread mais commençons par voir ce que ça implique ?&lt;/p&gt;
&lt;p&gt;Les bons côtés :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jamais d&#39;accès concurrents aux données ;&lt;/li&gt;
&lt;li&gt;Le debuggage est nettement simplifié.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les mauvais côtés :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vous pouvez bloquer votre application avec du code un peu trop gourmand ;&lt;/li&gt;
&lt;li&gt;On ne peut pas faire confiance aux timers (setTimeout et setInterval) qui ont une précision approximative.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour se convaincre à la fois des bons et des mauvais côtés voici un petit bout de code qui va l&#39;illustrer.
Considérez le code suivant :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;done&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;importantThingToDo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// -&gt; &quot;done&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;timeConsumingFunction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// -&gt; &quot;start&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dans ce code, je suis sûr et certain que ma console affichera &amp;quot;start&amp;quot; en premier même si l&#39;exécution de timeConsumingFunction() prend bien plus de 100ms.
Si setTimeout avait créé un nouveau thread, je n&#39;aurais pas pu prédire si ma console allait afficher &amp;quot;start&amp;quot; puis &amp;quot;done&amp;quot; ou le contraire.
Autre chose à prendre en compte, si l&#39;exécution de timeConsumingFunction prend plus que 100ms, importantThingToDo sera retardée. Si vous ajoutez à ça des interactions utilisateurs, vous pourrez encore retarder un peu son exécution.&lt;/p&gt;
&lt;h2 id=&quot;les-timers&quot; tabindex=&quot;-1&quot;&gt;Les timers&lt;/h2&gt;
&lt;p&gt;Les timers (setTimeout et setInterval) sont nos outils pour faire du code asynchrone avec Javascript. On se donnerait presque l&#39;impression qu&#39;on créé des threads et pourtant ...
En réalité il ne faut pas voir les timers comme des fonctions asynchrones mais plutôt comme des gestionnaires de queue. Et oui, la fonction principale des timers est d&#39;empiler des fonctions qui seront exécutées séquentiellement et au plus tôt n millisecondes plus tard.
Le paramètre de temps prend alors une signification un peu différente de celle à laquelle on pourrait penser. Au lieu de :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Exécute cette fonction dans n millisecondes&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;il faut plutôt avoir en tête :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Dès que tu es dispo après n millisecondes, exécute cette fonction&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;D&#39;où la faible fiabilité des timers Javascript.&lt;/p&gt;
&lt;p&gt;Pour une explication un peu plus complète sur le fonctionnement des timers de Javascript, je vous invite à lire l&#39;article &lt;a href=&quot;http://ejohn.org/blog/how-javascript-timers-work/&quot;&gt;How JavaScript Timers Work&lt;/a&gt; de John Resig dont je me suis beaucoup inspiré pour mon article.&lt;/p&gt;
&lt;h2 id=&quot;les-%C3%A9v%C3%A9nements%2C-le-secret-des-op%C3%A9rations-asynchrones&quot; tabindex=&quot;-1&quot;&gt;Les événements, le secret des opérations asynchrones&lt;/h2&gt;
&lt;p&gt;Vous avez dû souvent aussi entendre que Javascript était Event Driven et en effet, si vous y regardez de plus près, l&#39;exécution de code Javascript se fait toujours dans le cadre d&#39;un événement envoyé par le navigateur (load, click, mouseover, progress ...). Ensuite c&#39;est à vous, développeur, de définir ce qu&#39;il va se passer en fonction de ces événements.&lt;/p&gt;
&lt;p&gt;Je disais dans la section sur les timers que les timers empilaient des fonctions Javascript, en réalité c&#39;est le navigateur qui s&#39;occupe de cette tâche. Le navigateur va utiliser un timer interne (qui lui est précis) et enregistrer votre callback sur l&#39;événement de fin de timer. Au bout des n que vous aurez définit, il va ajouter dans la pile d&#39;exécution du moteur Javascript la fonction que vous aurez affecter au timer. Dès que le moteur Javascript sera libre, il s&#39;occupera alors de votre callback.&lt;/p&gt;
&lt;p&gt;Ce schéma se retrouve pour tous les événements qui se produisent dans le navigateur. Prenons l&#39;exemple du clic, voici ce qui se passe quand l&#39;utilisateur clique sur un élément :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le navigateur intercepte le clic ;&lt;/li&gt;
&lt;li&gt;il vérifie les listeners que vous aurez définis ;&lt;/li&gt;
&lt;li&gt;il les ajoute dans la pile d&#39;exécution de Javascript ;&lt;/li&gt;
&lt;li&gt;quand le moteur est disponible, il exécute chacun des listeners ;&lt;/li&gt;
&lt;li&gt;à la fin de chaque listener le navigateur joue l&#39;action par défaut (par exemple naviguer lors d&#39;un clic sur un lien) si aucun des listeners n&#39;a joué preventDefault() sur l&#39;événement.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Toutes les actions asynchrones de Javascript fonctionnent sur ce modèle. Par exemple les requêtes XMLHttpRequest laissent au navigateur le soin de faire la requête puis de prévenir le moteur JS une fois que la requête est finie. Seulement contrairement aux timers, vous ne pourrez jamais prédire quand une requête AJAX sera finie. Par exemple le code suivant :&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; request &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;GET&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;/url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;request done&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;timeout ended&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vous ne pourrez pas dire si votre console va vous afficher &amp;quot;request done&amp;quot; puis &amp;quot;timeout ended&amp;quot; ou le contraire puisque vous n&#39;avez aucune idée de quand l&#39;événement load sera lancé.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Je pense qu&#39;il est important de bien comprendre le fonctionnement interne des technologies que nous utilisons afin de bien les utiliser. Pour Javascript, S&#39;il y a bien quelque chose à retenir c&#39;est que Javascript n&#39;éxécute qu&#39;un seul morceau de code à la fois ! En gardant bien ça en tête vous verrez que certains comportements que vous ne vous expliquiez pas deviendrons clair.&lt;/p&gt;
&lt;p&gt;Et juste pour voir si vous avez bien compris, que donnera l&#39;exécution de ce bout de code ? (Pas le droit d&#39;utiliser sa console hein ;) )&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    a &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Batman&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    a &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;nan &#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;NB : Sachez tout de même qu&#39;il existe maintenant les &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers&quot;&gt;web workers&lt;/a&gt; qui permettent de créer des threads sur lesquels vous avez la main.&lt;/p&gt;
</content>
  </entry>
</feed>