<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 3Shain</title>
    <description>The latest articles on DEV Community by 3Shain (@3shain).</description>
    <link>https://dev.to/3shain</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F615991%2Fc3d7cb51-7f84-44f4-93df-1495463d792d.png</url>
      <title>DEV Community: 3Shain</title>
      <link>https://dev.to/3shain</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/3shain"/>
    <language>en</language>
    <item>
      <title>On state mutation on changes of state</title>
      <dc:creator>3Shain</dc:creator>
      <pubDate>Thu, 31 Mar 2022 08:45:17 +0000</pubDate>
      <link>https://dev.to/3shain/on-state-mutation-on-changes-of-state-336n</link>
      <guid>https://dev.to/3shain/on-state-mutation-on-changes-of-state-336n</guid>
      <description>&lt;p&gt;In this post we will investigate a interesting but rarely thought "problem" of reactivity: &lt;strong&gt;state mutation inside effect caused by a previous state mutation.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In this post, the usage of word 'state' is in the context of reactivity - capable to raise (side) effects.&lt;br&gt;
e.g. &lt;code&gt;createSignal&lt;/code&gt; - &lt;code&gt;createEffect&lt;/code&gt; in solidjs, &lt;code&gt;ref&lt;/code&gt; - &lt;code&gt;watch&lt;/code&gt; in vue, even React Hooks can fall into this category.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How is that a "problem"? Well obviously there is a recursion-like structure or circular definition in that sentence - like &lt;strong&gt;state mutation&lt;/strong&gt; inside effect caused by a previous &lt;strong&gt;state mutation&lt;/strong&gt; inside effect cased by a previous &lt;strong&gt;state mutation&lt;/strong&gt;...... maybe it will eventually stop at some point or never stop. I personally didn't dislike recursions, I want my code to be predictable though. So if I really need a recursion, I will try to make it as local as possible (or convert to an iteration). However, reactivity inevitably inverts your flow of control. You are asked to set the (source) state and never care what's going to happen (the merit from Separation of Concern), so you are not sure about whether the current mutation will cause another state be mutated, unless - &lt;strong&gt;state mutation inside effect is completely forbidden&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;How is that possible? I rephrase the question - Is there any functionality that is only achievable by state mutation inside effect? &lt;/p&gt;

&lt;p&gt;My answer is no, if you don't mean to construct a recursion. The secret is the implicit dependency and circular reference possibly caused by that implicit dependency. The mutated state in effect is &lt;strong&gt;implicitly depending on&lt;/strong&gt; the state(s) raising that effect, that's intuitive. And if the latter is already explicitly depending on the former, there is a circular dependency constructed. If the recursion never converges , sometimes the reactivity implementation will be able to identify this, but that's just better than getting stackoverflow or infinite loop if the implementation "smartly" utilises the eventloop. Actually some recursion can be proved to converge but most of time you get a convergent recursion &lt;em&gt;accidentally&lt;/em&gt; to work, and it is like a landmine that is ready to f-word up everything when you start refactoring (or you cordon off code "LEGACY CODE, IT'S WORKING, DO NOT TOUCH"). Anyway you are not advised to implement recursion based on reactivity (hard to maintain because the control is inverted), and every-time you construct a recursion is by accident. So state mutation could be simply banned for recursion construction.&lt;/p&gt;

&lt;p&gt;But what about those non-recursion cases? Since not all mutations will form a circular dependency. Well most of reactivity implementations provide a functionality to declare a state &lt;strong&gt;derivation&lt;/strong&gt; (like &lt;code&gt;createMemo&lt;/code&gt; in solidjs), that's an obvious solution if a state &lt;em&gt;unconditionally&lt;/em&gt; depends on another one. As for &lt;em&gt;conditional&lt;/em&gt; derivation, just one more thing, the previous value (which might be provided already in the API, or store the latest state into somewhere non-reactive (e.g. &lt;code&gt;useRef&lt;/code&gt; of react) when effect triggered), so if the condition is false, just return the previous value. In conclusion we are converting implicit dependency into explicit one.&lt;/p&gt;

&lt;p&gt;I'm just about to say &lt;strong&gt;you don't need state mutation inside effect&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But I soon come up with a made-up use case: there are state A,B,C and two effects mutating C triggered by corresponding changes of A,B. It's neither a case of circular dependency nor solvable by methods mentioned above. So far I think this is an anti-pattern, as the concern of control flow is leaked into reactivity - what if A, B changed at the same time, the execution order of effects does matter, while a reactivity implementation does not necessarily offer guarantees.&lt;/p&gt;

&lt;p&gt;What's your opinion? Feel free to talk about in comments.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>reactivity</category>
    </item>
    <item>
      <title>On Front-end Dependency Injection</title>
      <dc:creator>3Shain</dc:creator>
      <pubDate>Sat, 26 Mar 2022 11:18:13 +0000</pubDate>
      <link>https://dev.to/3shain/on-front-end-dependency-injection-4a68</link>
      <guid>https://dev.to/3shain/on-front-end-dependency-injection-4a68</guid>
      <description>&lt;p&gt;Just recently I had a good conversation with &lt;a class="mentioned-user" href="https://dev.to/samwightt"&gt;@samwightt&lt;/a&gt;   about the design of Context (not limited to react but as a general Dependency Injection mechanism). Several conclusions are made and some problems (objectively) come to light. So I wrote this memo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context (DI) compares to Props
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Related: &lt;a href="https://blog.testdouble.com/posts/2021-03-19-react-context-for-dependency-injection-not-state/"&gt;React Context for Dependency Injection Not State Management (testdouble.com)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Both of them pass information down (from parent to children) so they seem to be comparable. A good starting point is trying to answer the question: what will happen if there is only props/context available.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If only props available, it's easy to get "props drilling" if the children requiring information is 'far away' from the parent providing such information.

&lt;ul&gt;
&lt;li&gt;To solve props drilling, we should try &lt;strong&gt;not&lt;/strong&gt; encapsulate subcomponents as much as possible but that's not ideal (as Separation of Concern) and sometimes subcomponents need to manage their own local state.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;If only context available, the View (template) is hard to be represented.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Seems being without context is acceptable and context is more likely a complement to props.&lt;/p&gt;

&lt;p&gt;But that's not a satisfying answer to me. I have a more radical statement: &lt;strong&gt;Props for View, Context for Model&lt;/strong&gt;. That means&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Props are accessed and should be only accessed in template&lt;/li&gt;
&lt;li&gt;Model is only accessible via Context (Dependency Injection)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason why this is not obvious (at least in React) is that &lt;em&gt;React Context&lt;/em&gt; are not designed for passing frequently changed state. But if the state is a reference-stable reactive container (that you can subscribe to get the value changes) then it becomes applicable (that's exactly how Redux works in React).&lt;/p&gt;

&lt;p&gt;By locking props in view, props drilling will be automatically prevented from you because you are limited to abuse props (grabbing everything from props). The Model and View are decoupled, and Context(DI) is the only bridge connecting up them.&lt;/p&gt;

&lt;p&gt;There is a better interpretation: State drive view (as side effect) and for children components props can drive view because &lt;strong&gt;props are delegate of state from parent&lt;/strong&gt; (props as actual argument). Also for parent components &lt;strong&gt;props are delegate of children's side effect (of view)&lt;/strong&gt; (props as formal parameter)&lt;/p&gt;

&lt;p&gt;Also this implies the component should be either fully controlled or fully uncontrolled. Not possible to mutate internal state on changes of props.&lt;/p&gt;

&lt;p&gt;But I found an exception: list rendering of components which have their own model. This kind of component will probably need to read a &lt;strong&gt;constant&lt;/strong&gt; prop which identify the identity of current model (not to be confused with &lt;em&gt;key&lt;/em&gt; but they probably get the same value). That's the only case I found the model has to read props. To solve it, render list with pure component only (but it might be not always applicable)&lt;/p&gt;

&lt;h3&gt;
  
  
  DI introduce coupling and it doesn't matter
&lt;/h3&gt;

&lt;p&gt;Although I don't see how DI introduce coupling, while someone argues that the component consuming data from Context is coupled with the corresponding provider. Are they coupled? Yes and No?! They are coupled because the business requires them to be coupled. They are not coupled because DI are designed to decouple things. Are they talking about the same coupling?...&lt;/p&gt;

&lt;p&gt;A not so appropriate metaphor: you have legal relationships with your family members, is that kind of coupling? (no pun)&lt;/p&gt;

&lt;p&gt;One thing objectively obvious is that, a component &lt;em&gt;needs some information&lt;/em&gt;, no matter how it's delivered. Some need very few (like UI controls) and some requires &lt;em&gt;more contexts&lt;/em&gt; especially those related to your business. It's also worth noting that, we divide components into smaller components (Separation of Concern applied?), by simply the visual layout but not the information required. Now you heavily rely on props and think it's explicit and low-coupling (just provide props to use the component, very great reusability!) but now every other components using it but can't provide all of required props will simply throw these to where they are used, and then the same pattern will spread like a virus (props drilling, exactly). That means &lt;em&gt;some components declare a prop not because they need it but their children in template need it&lt;/em&gt;. The conclusion is either these component are actually coupled via prop definitions, or The Principle of Least Privilege is violated (you know something you don't need to know).&lt;/p&gt;

&lt;p&gt;And a more interesting conclusion come out:   not all the components have the same reusability (not a binary 'reusable vs non-reusable', but a possibility of being reused), no matter how pure it is or not, a &lt;code&gt;&amp;lt;Button&amp;gt;&lt;/code&gt; tends to be reused more than &lt;code&gt;&amp;lt;GoodItemDetail&amp;gt;&lt;/code&gt; because the latter &lt;em&gt;need more contexts&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Just grab from environment
&lt;/h3&gt;

&lt;p&gt;Is that hard to declare a variable at top level and directly import it from components? Yes sometime it works. It's also known as Singleton and if you think your application is a singleton, just go for it. I don't think so though.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design of API and Hidden Dependency
&lt;/h2&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/samwightt"&gt;@samwightt&lt;/a&gt;  points out a weakness of current React Context API design: you don't know which contexts the component depends on, from the type definition. And I see some down side of flexibility of &lt;code&gt;useContext&lt;/code&gt; hooks and the Hooks design itself - too flexible to be abused.&lt;/p&gt;

&lt;p&gt;He compared Angular which has built-in DI and forces dependencies to be declared in constructor. One thing obvious is that a Angular service is more easy to test than a custom React Hook which uses context, because for the former you can just provide some Mock/Double/Spy objects (without enabling DI mechanism), But for the latter, firstly you have no idea what the custom hook depend on, secondly the provided context is probably a &lt;em&gt;internal&lt;/em&gt; thing encapsulated by third party that you shouldn't directly rely on (like &lt;code&gt;useXXXQuery&lt;/code&gt; grabbing a cache management implementation that doesn't exposed as a public API), so you must build a mini application with least working requirement to test a single hook. The first issue could be solved by generators - collecting yielded type you will be able to get a union type of all dependencies. But the second point so far I think it's really unbeatable...... I understand why he thought the React Context is magical. &lt;/p&gt;

&lt;p&gt;Being magical is not necessary a bad thing but I can't help trying to think a more explicit design of API, and how it would impact the current mental modal. I really love the current one but it could be improved further. I'm still investigating into this.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To be continue&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>react</category>
      <category>angular</category>
      <category>javascript</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Promise Cancellation &amp; semantic behind it</title>
      <dc:creator>3Shain</dc:creator>
      <pubDate>Mon, 26 Jul 2021 10:23:43 +0000</pubDate>
      <link>https://dev.to/3shain/promise-cancellation-semantic-behind-it-403p</link>
      <guid>https://dev.to/3shain/promise-cancellation-semantic-behind-it-403p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR: We do not cancel Promise but operations. &lt;em&gt;Cancellation&lt;/em&gt; is orthogonal to the abstraction of Promise. They have different concerns.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many people have asked: I want a Promise with &lt;code&gt;.cancel()&lt;/code&gt; method!&lt;/p&gt;

&lt;p&gt;Okey. Let's assume we have one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://somedata.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;//... at some point&lt;/span&gt;
&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To not violate the original Promise/A+ spec, when it's cancelled (and in PENDING status), reject with an error (may name it &lt;code&gt;CancelledError&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;And here's the problem: When &lt;code&gt;.cancel()&lt;/code&gt; applied, which promise on the chain is really cancelled? &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Top(then "downstream" get notified by catching &lt;code&gt;CancelledError&lt;/code&gt; and re-throwing it)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But what if a part of Promises on the chain have resolved? A settled Promise can't modify its state, therefore it can't "notify" its "downstream" again.&lt;br&gt;
If "upstream" is PENDING, what about other "downstream"s?&lt;/p&gt;


&lt;/blockquote&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://somedata.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// ...at some point, root is PENDING&lt;/span&gt;
&lt;span class="nx"&gt;promise1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// what about promise2?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Current (but don't care about "upstream")&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hmmm, it is &lt;code&gt;.ignore()&lt;/code&gt; rather than &lt;code&gt;.cancel()&lt;/code&gt;. Not really what we expected.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Current (and cancel "upstream", if possible, i.e. no other "downstream" waiting for a value)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This intuitively makes better sense. But things get really complicated. This is to say explicit dependencies between CancellablePromise need to be managed.....&lt;/p&gt;

&lt;p&gt;Actually the two made-up terms "upstream" and "downstream" do not exist in Promise/A+ spec at all. A Promise has no clue how it will be fulfilled/rejected. &lt;/p&gt;

&lt;p&gt;Maybe &lt;a href="https://rxjs.dev/"&gt;RxJS&lt;/a&gt; has done this job.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Seems there is no natural behavior and clear semantic of Promise &lt;em&gt;cancellation&lt;/em&gt;. Is &lt;em&gt;cancellable Promise&lt;/em&gt; just a wrong abstraction?&lt;br&gt;
Think about the question again. Is it the Promise we want to cancel?&lt;/p&gt;

&lt;p&gt;IMO &lt;strong&gt;we want to cancel should be the operation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recall the definition of Promise: A &lt;em&gt;promise&lt;/em&gt; represents the eventual result of an asynchronous operation. It &lt;strong&gt;promises&lt;/strong&gt; you there will be a value or error (that's why it is called Promise). While when we talk about a cancellation, we often mean to abort the procedure and if necessary dispose related resources (to prevent memory leak). To strictly speak &lt;em&gt;cancellation&lt;/em&gt; is orthogonal to the abstraction of Promise. &lt;strong&gt;They have different concerns.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So we need something else to explicitly manage cancellation, e.g. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController"&gt;AbortController&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// an example of aborting ongoing fetch&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AbortController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ...at some point&lt;/span&gt;
&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I know it's verbose, but to manage cancellation separately makes the most sense.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
    </item>
    <item>
      <title>await Promise !== coroutine</title>
      <dc:creator>3Shain</dc:creator>
      <pubDate>Sun, 25 Jul 2021 11:10:59 +0000</pubDate>
      <link>https://dev.to/3shain/promise-coroutine-548i</link>
      <guid>https://dev.to/3shain/promise-coroutine-548i</guid>
      <description>&lt;p&gt;Yeah this is a sister post of &lt;a href="https://dev.to/3shain/inversion-of-inversion-of-control-212p"&gt;Inversion of Inversion of Control&lt;/a&gt;. In that post I've illustrated the idea of coroutine (which invert the inverted control back) implemented by async/await. However, here I'd like to investigate it in depth and conclude that async/await syntax is not strictly coroutine.&lt;/p&gt;

&lt;p&gt;Let's see an example.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Edb22Die--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1003930764852031488/boV5pzoa_normal.jpg" alt="Ingvar Stepanyan profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Ingvar Stepanyan
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @rreverser
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Before:&lt;br&gt;(function animate() {&lt;br&gt;  ...&lt;br&gt; requestAnimationFrame(animate);&lt;br&gt;})();&lt;br&gt;&lt;br&gt;Nowadays:&lt;br&gt;const nextFrame = () =&amp;gt; new Promise(resolve =&amp;gt; requestAnimationFrame(resolve));&lt;br&gt;&lt;br&gt;(async function animate() {&lt;br&gt;  while (true) {&lt;br&gt;    ...&lt;br&gt;    await nextFrame();&lt;br&gt;  }&lt;br&gt;})();
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      10:56 AM - 21 Jul 2021
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1417800541133058050" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1417800541133058050" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1417800541133058050" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;The code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextFrame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ... maybe we should add an exit/break condition&lt;/span&gt;
    &lt;span class="c1"&gt;// lovely in-control-render-loop&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nextFrame&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it has a problem: &lt;strong&gt;Your code is not executed in rAF callback synchronously but a micro-task callback&lt;/strong&gt;. So intuitively you get zero benefit from using rAF.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ironically you might never notice this as some implementations do cover the case. See &lt;a href="https://github.com/whatwg/html/issues/2637"&gt;Timing of microtask triggered from requestAnimationFrame&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's due to the spec of Promise: always trigger a micro-task. But in a real coroutine, &lt;strong&gt;the control is expected to be resumed at a specific point, synchronously.&lt;/strong&gt; The rAF is such an example, and some libraries/frameworks would use black magic side-effect-ish global variable to store context informations in a synchronous procedure. (And luckily JavaScript is single-threaded, otherwise...). Anyway &lt;strong&gt;we need control back immediately, not delegated by a micro-task&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Someone may ask: why a Promise must be asynchronous? Can't we have a synchronous Promise? (off-topic: the executor function in Promise constructor is executed synchronously.) The answer is: it could be but it shouldn't be. Having an asynchronous model simplifies the design, as Promise represents the eventual result of an asynchronous operation. For a Promise we only concern the &lt;strong&gt;value&lt;/strong&gt; (and/or &lt;strong&gt;reason for no value&lt;/strong&gt;). So a Promise just tell you "I'll eventually give you a value but not sure about when it's available (and doesn't necessarily to be in a micro-task.)". Even a fulfilled/rejected Promise notifies the value asynchronously, to make the design &lt;strong&gt;consistent&lt;/strong&gt;. So you know the callback in &lt;code&gt;.then&lt;/code&gt; is always deferred. Otherwise,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// not runnable code, for illustration purpose&lt;/span&gt;
&lt;span class="nx"&gt;aMaybeSyncPromise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// assume an error is thrown in callback&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Oops!!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// or access a closure variable&lt;/span&gt;
  &lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'y' is undefined if sync&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// ... original flow of control&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a sync and async callback give different behavior.&lt;/p&gt;

&lt;p&gt;So let's go back to coroutine. Can we have a proper coroutine in JavaScript? Of course, by Generator. You can implement your own scheduler, and decide when to return the control back. (But it doesn't seem to be easy as it is described 😅. I planned to list some implementations here but none of them is Promise-free). I'll continue on this topic.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Inversion of Inversion of Control</title>
      <dc:creator>3Shain</dc:creator>
      <pubDate>Sat, 24 Jul 2021 15:32:08 +0000</pubDate>
      <link>https://dev.to/3shain/inversion-of-inversion-of-control-212p</link>
      <guid>https://dev.to/3shain/inversion-of-inversion-of-control-212p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://martinfowler.com/bliki/InversionOfControl.html"&gt;Inversion of Control&lt;/a&gt; is a common phenomenon that you come across when extending frameworks. Indeed it's often seen as a defining characteristic of a framework. -- Martin Fowler&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The key part is the 'framework' calls you rather than you calling the 'framework'. The 'framework' doesn't need to be any specific thing. An operating system, a language runtime, or an application framework could be that 'framework'. As you register an event handler (no matter explicit .addEventHander or implicit lifecycle), you are already using IoC.&lt;/p&gt;

&lt;p&gt;But is IoC always good? Or we should say, &lt;strong&gt;is IoC always what we desired?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;IMO most of IoC is not intended (DI is the one I think of so far), but &lt;strong&gt;the control is by nature inverted, especially in human-computer interaction programming&lt;/strong&gt;, because this is how the computer works: it is the user controls. If user doesn't input then the program just keeps idling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The example provided in the blog above &lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'What is your name?'&lt;/span&gt;
&lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;gets&lt;/span&gt;
&lt;span class="n"&gt;process_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'What is your quest?'&lt;/span&gt;
&lt;span class="n"&gt;quest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;gets&lt;/span&gt;
&lt;span class="n"&gt;process_quest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then here comes a question: why does command line enquiry seem to keep the control? Isn't the thread blocking and waiting for a signal as well? That is true and in fact the computer is in certain degree event-driven, in form of interruptions. However, conceptually it is in control because it's an imperative process: statements executed in order. There is a clear flow of control.&lt;/p&gt;

&lt;p&gt;And I think &lt;strong&gt;sometimes we need our control back.&lt;/strong&gt; Like when there are callback hells. And luckily coroutine(async/await) is to rescue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// in control&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://bar.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// control inverted&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://bar.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
  &lt;span class="c1"&gt;// we get two flows of control now?&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe this example is so simple that you don't see any difference :/. So let's see another example: you are going to manage a WebSocket connection and it has some rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;when connected, server sends you 'LOGIN' and you should reply 'LOGIN:&amp;lt;auth token&amp;gt;' and finally when server replies 'VERIFIED' the connection is successful.&lt;/li&gt;
&lt;li&gt;whenever server sends 'PING', client must reply 'PONG' (in 30 seconds maybe) otherwise connection will be closed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Normally WebSocket is event-driven and we might write a version like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo.bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isVerified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOGIN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOGIN:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;VERIFIED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;isVerified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PING&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PONG&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// process the data&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code might work. But there are edge cases like what if server doesn't reply the expected message? To add more state (isLogined, isSuccessful) is a solution but it's redundant (you might check current state whenever callback executed), and not easily-extendable if there are more steps.&lt;/p&gt;

&lt;p&gt;However if the control is inverted, the logic will become much more natural. Imagine we have a &lt;code&gt;IoCWebSocket&lt;/code&gt; and it provides a modified &lt;code&gt;WebSocket&lt;/code&gt; with extra methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// resolve when it's open&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// resolve when there is a incoming message&lt;/span&gt;
&lt;span class="c1"&gt;// reject when websocket error&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;read&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the logic becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;IoCWebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo.bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="c1"&gt;// assume inside an `async` function body&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;read&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOGIN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unexpected reply &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOGIN:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;read&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;VERIFIED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unexpected reply &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;read&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PING&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PONG&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// process the data&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// may catch error and re-throw if it's not due to connection closed.&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you notice the order (which is an implicit rule) is naturally guaranteed?&lt;/p&gt;

&lt;p&gt;And we may have many analogous situations like drag-n-drop, step-by-step enquiry, &lt;a href="https://en.wikipedia.org/wiki/Konami_Code"&gt;cheat codes&lt;/a&gt;, (stateful) animations and interactions(hold to activate/n-times click)......they are procedures with extra (temporary) context informations, they're designed to have an order, they could own their own flow of control.&lt;/p&gt;

&lt;p&gt;Bonus: &lt;a href="http://eli.thegreenplace.net/2009/08/29/co-routines-as-an-alternative-to-state-machines/"&gt;Co-routines as an alternative to state machines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is about 'what'. As for 'how', I'm still investigating the most optimal solutions. &lt;code&gt;Promise&lt;/code&gt; and async/await are fine in most cases. Sister post: &lt;a href="https://dev.to/3shain/promise-coroutine-548i"&gt;Promise!==coroutine&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
