<?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: JayZho</title>
    <description>The latest articles on DEV Community by JayZho (@jayzho).</description>
    <link>https://dev.to/jayzho</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%2F811581%2Fdc357407-8a38-422e-9272-603acd620b31.png</url>
      <title>DEV Community: JayZho</title>
      <link>https://dev.to/jayzho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jayzho"/>
    <language>en</language>
    <item>
      <title>Understand Async in JS: the core concepts</title>
      <dc:creator>JayZho</dc:creator>
      <pubDate>Wed, 12 Oct 2022 05:24:26 +0000</pubDate>
      <link>https://dev.to/jayzho/understand-async-in-js-the-core-concepts-1j92</link>
      <guid>https://dev.to/jayzho/understand-async-in-js-the-core-concepts-1j92</guid>
      <description>&lt;h1&gt;
  
  
  1. Components of JS in the Browser
&lt;/h1&gt;

&lt;p&gt;When people talk about "Javascript" nowadays they are most likely refering to the combination of &lt;strong&gt;Javascript + Browser&lt;/strong&gt;. Strictly speaking, "Javascript" by itself is just a programming language with an interpreter(e.g. Chrome's V8 engine) that understands Javascript's syntax and semantics and converts the JS code you write to some lower level runnable code.&lt;/p&gt;

&lt;p&gt;You might have wondered how JS is able to do asynchronous calls while itself being a single-threaded programming language. And the fun fact is, you were right, JS actually cannot. It's the runtime environment provided by browsers like Chrome and Safari that adds this extra async feature to the original JS. Apart from that, JS runtime environment also provides handy objects like &lt;strong&gt;DOM&lt;/strong&gt; and &lt;strong&gt;BOM&lt;/strong&gt;, which lets you interact with the elements in the HTML and the browser respectively. &lt;/p&gt;

&lt;p&gt;When you write something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document.getElementById("myDog").classList.remove("bad-dog")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you're using a feature provided by the JS runtime environment, namely, the DOM to interact with the elements inside HTML. &lt;/p&gt;

&lt;p&gt;And when you wanna output the width of the screen and to load the previous URL in the history list, you might do something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(screen.width)
history.back()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, you're accessing the objects &lt;code&gt;screen&lt;/code&gt; and &lt;code&gt;history&lt;/code&gt; provided by BOM, which is another feature in the JS runtime environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aCipXaWY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6xd2vcteu2644mjcvyf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aCipXaWY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6xd2vcteu2644mjcvyf.png" alt="Image description" width="880" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, it's really the runtime environment provided by a web browser on top of JS that allows us to build amazing things using the language Javascript. Hence, it's essential to have the clear picture in mind that &lt;strong&gt;Javascript&lt;/strong&gt; in modern browsers refers to the combination of &lt;strong&gt;Javascript Engine&lt;/strong&gt; and &lt;strong&gt;Javascript Runtime Environment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Note that it's not only browsers that provide runtime environment for JS, for example, node.js also provides a runtime environment for locally running JS code. &lt;/p&gt;

&lt;p&gt;For this blog, we'll only focus on the browser side.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. The Async Mechanism
&lt;/h1&gt;

&lt;p&gt;As mentioned above, JS is a single-threaded language. Therefore, the async feature is provided by JS rutime environment in the browser. To get a clear picture of this async mechanism, let's first understand the &lt;strong&gt;Call Stack&lt;/strong&gt;.&lt;br&gt;
Say we have this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fuction a() {
    console.log("a")
}

function b() {
    a()
    console.log("b")
}

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

&lt;/div&gt;



&lt;p&gt;The call stack of this chunk of code follows the "First in Last out" principle, meaning that the innermost function finishes first and the outermost function finishes the last:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mLUEdXr8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0z4binwk2gommmljmr0z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mLUEdXr8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0z4binwk2gommmljmr0z.png" alt="Image description" width="880" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we add in some async task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function timesUp() {
    console.log("timesUp!")
}

console.log("before async")
setTimeout(timesUp, 1000)
console.log("after async")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the asychronous code setTimeout() is added, the async function call behaves like a normal sync function which finishes immediately and let the call stack continue. &lt;br&gt;
But from this point on, the browser secretly runs the async code in parallel(in C++ for Chrome) to the synchronous JS code, and when the async task is done, the browser pushes the callback function of this async task to a data structure known as the &lt;strong&gt;Event Queue&lt;/strong&gt;, which follows the "First in First out" principle. And there comes our &lt;strong&gt;Event Loop&lt;/strong&gt; guy, who is constantly checking if the call stack is empty, and if yes it pops the event queue and pushes onto the call stack, then the pushed callback function from the event queue will be executed normally as a synchronous function:&lt;/p&gt;

&lt;p&gt;Pushing &lt;code&gt;console.log("before async")&lt;/code&gt; to the call stack&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q6IZqUvR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wayemnhs4ff8n2y6nfi3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q6IZqUvR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wayemnhs4ff8n2y6nfi3.png" alt="Image description" width="880" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Function finishes&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PHBJ_QVq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kh4r8n5swp5hhxt4gndo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PHBJ_QVq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kh4r8n5swp5hhxt4gndo.png" alt="Image description" width="880" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pushing &lt;code&gt;setTimeout()&lt;/code&gt; onto the call stack&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nDZLzZGp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfnq5k7p2puxkg4nxneo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nDZLzZGp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfnq5k7p2puxkg4nxneo.png" alt="Image description" width="880" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Async function call finishes immediately and gets run in the background by the browser, while the call stack continues to call &lt;code&gt;console.log("after async")&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eFmoq6pZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7bau9wht7dm55r4y5hdn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eFmoq6pZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7bau9wht7dm55r4y5hdn.png" alt="Image description" width="880" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;console.log()&lt;/code&gt; finishes, the timer keeps running until 1000 milliseconds has passed&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--icjF7xjZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/isysd8n2xjkv2fwyefh0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--icjF7xjZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/isysd8n2xjkv2fwyefh0.png" alt="Image description" width="880" height="662"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Async task done, its callback function gets pushed:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5j5Dgk8V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2q8r0vtlkakue7r1seu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5j5Dgk8V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2q8r0vtlkakue7r1seu.png" alt="Image description" width="880" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Event Loop grabs the callback and pushes to the call stack:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UXQjx4xl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0o6nn9p30s96drc5e7gf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UXQjx4xl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0o6nn9p30s96drc5e7gf.png" alt="Image description" width="879" height="665"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The call stack executes as usual:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RnUsyzGW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/os469oz67t0nsktqfs4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RnUsyzGW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/os469oz67t0nsktqfs4s.png" alt="Image description" width="879" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NpukN-ag--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2wzg7blj4cdxlff5s7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NpukN-ag--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2wzg7blj4cdxlff5s7d.png" alt="Image description" width="880" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DHEuOo2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s3276ic68prs9lqp27g0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DHEuOo2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s3276ic68prs9lqp27g0.png" alt="Image description" width="877" height="658"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that in the diagrams above, the &lt;strong&gt;Web API&lt;/strong&gt;, &lt;strong&gt;Event Queue&lt;/strong&gt; and &lt;strong&gt;Event Loop&lt;/strong&gt; are all part of the JS runtime environment, meaning that they don't belong to the JS engine but instead are powered by the browser, without which we cannot run async code in JS.&lt;/p&gt;

&lt;p&gt;Now that we understand the mechanism behind async events, we can see that the code below doesn't just give "setTimeout" a zero delay for no reason:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setTimeout(() =&amp;gt; console.log("call stack empty, I'm from the event queue!"), 0)
console.log("call stack busy")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  3. Promises
&lt;/h1&gt;

&lt;h3&gt;
  
  
  3.1 The motivation
&lt;/h3&gt;

&lt;p&gt;Just because Promises are normally used in conjunction with async tasks, we shouldn't be tricked into thinking that by wrapping a function into a Promise, we turn it into async.(at least that's what I thought initially)&lt;/p&gt;

&lt;p&gt;Promises are simply a syntactic sugar -- something that helps us format our code in a better way, but really it's just another way to specify(especially chain) callback functions.&lt;/p&gt;

&lt;p&gt;Say you got an async function "asyncFunc", which takes in two callback functions, one to call on a success, the other one to call on an exception:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function asyncFunc(success_callback, failure_callback);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The way to turn it into a Promise is simply wrapping this "asyncFunc" by another function that also takes 2 callback functions, which are named "resolve" and "reject" by convention, and passing them into "asyncFunc" accordingly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const promisedAsyncFunc = new Promise(
    (resolve, reject) =&amp;gt; {
        asyncFunc(resolve, reject)
    }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we're able to specify its callbacks by append a &lt;code&gt;.then()&lt;/code&gt; instead of nesting them into its arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function successCallback() {
    console.log("yay")
}

function failureCallback() {
    console.log("oh no")
}

//traditional callback passing
asyncFunc(successCallback, failureCallback)

//using Promise
promisedAsyncFunc.then(successCallback, failureCallback)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might seem redundant at the moment, but imagine you also have further callbacks to pass into your callbacks, what easily turns into a "Callback Hell", something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setTimeout(() =&amp;gt; {
    setTimeout(() =&amp;gt; {
        setTimeout(() =&amp;gt; {
            console.log("3 seconds has passed")
        }, 1000)
    }, 1000)
}, 1000)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By wrapping setTimeout() in a Promise, we can specify its callback function by putting it in the &lt;code&gt;.then()&lt;/code&gt; function, which can accept another &lt;code&gt;.then()&lt;/code&gt; to specify the callback function of this callback function. (&lt;strong&gt;but only if the former callback function also returns a Promise&lt;/strong&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function promisedSetTimeout(interval) {
    return new Promise((resolve, reject) =&amp;gt; {
        setTimeout(resolve, interval)
    })
}

//now a non-recursive way for multiple layers of callbacks
promisedSetTimeout(1000)
.then(() =&amp;gt; promisedSetTimeout(1000))
.then(() =&amp;gt; promisedSetTimeout(1000))
.then(() =&amp;gt; console.log("3 seconds has passed"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore, the motivation of Promise is clear: we want to flatten the "recursiveness" of the callback hell.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Returning vs. Passing in
&lt;/h3&gt;

&lt;p&gt;In comparison to returning a Promise in the passed-in function of &lt;code&gt;.then()&lt;/code&gt;, we can also return a non-Promise data and still be able to chain it using &lt;code&gt;.then()&lt;/code&gt;.&lt;br&gt;
See the below example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function someSyncCode() {
    return new Promise((resolve, reject) =&amp;gt; {
        console.log("do task #1")
        resolve()
    })
}

someSyncCode()
    .then(() =&amp;gt; {
        console.log("do task #2")
        return "task #3"
    })
    .then((task) =&amp;gt; {
        console.log("got " + task) // got task #3
    })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which works the same as returning a Promise in the first &lt;code&gt;.then()&lt;/code&gt; and call &lt;code&gt;resolve("task #3")&lt;/code&gt; instead of directly returning that string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function someSyncCode() {
    return new Promise((resolve, reject) =&amp;gt; {
        console.log("do task #1")
        resolve()
    })
}

someSyncCode()
    .then(() =&amp;gt; {
        return new Promise((resolve, reject) =&amp;gt; {
            console.log("do task #2")
            resolve("task #3")
        })
    })
    .then((task) =&amp;gt; {
        console.log("got " + task)
    })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way to pipeline function calls might feel a bit counter-intuitive, especially if you've been only dealing with normal function pipeling, where a function must directly return something for the next function to use as its input. But that's exactly the power of Promise chaining, which allows us to flatten the "recursiveness" of callbacks.&lt;/p&gt;

&lt;p&gt;In short, a &lt;code&gt;.then()&lt;/code&gt; always expects a &lt;code&gt;Promise.resolve(output)&lt;/code&gt; object from its previous Promise, which then gets unwrapped and &lt;code&gt;output&lt;/code&gt; gets fed to this &lt;code&gt;.then()&lt;/code&gt;'s passed-in function. And we can return such an object in several ways:&lt;br&gt;
1.Return a &lt;code&gt;new Promise()&lt;/code&gt; and call &lt;code&gt;resolve()&lt;/code&gt; with data passed in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Promise.resolve().then(() =&amp;gt; {
    return new Promise((resolve, reject) =&amp;gt; {
        resolve("data")
    })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Return explicitly using &lt;code&gt;Promise.resolve("data")&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Promise.resolve().then(() =&amp;gt; {
    return Promise.resolve("data")
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Return just the data itself. Then &lt;code&gt;.then()&lt;/code&gt; will implicitly wrap &lt;code&gt;"data"&lt;/code&gt; with a Promise, hence it's equivalent to returning &lt;code&gt;Promise.resolve("data")&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Promise.resolve().then(() =&amp;gt; {
    return "data"
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just to clarify, the second example might not feel intuitive since what we did in the first &lt;code&gt;.then()&lt;/code&gt; is purely synchronous, making the need for passing the return value into a callback rather than immediately returning it seem unnecessary. The purpose is solely to compare the 2 ways of fulfilling a &lt;code&gt;.then()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So yes, in a practical situation, we would do an async task in the first &lt;code&gt;.then()&lt;/code&gt; if we're returning a Promise, something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.then(() =&amp;gt; {
    return new Promise((resolve, reject) =&amp;gt; {
        console.log("do task #2")
        setTimeout(() =&amp;gt; resolve("task #3"), 1000)
    })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Multi-layered Promises
&lt;/h3&gt;

&lt;p&gt;The Promise-unwrapping process in &lt;code&gt;.then()&lt;/code&gt; is recursive, meaning that no matter how many layers of Promises are wrapped around the innermost data, &lt;code&gt;.then()&lt;/code&gt; always unwraps them all until the data itself is revealed. Therefore, the simple example below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Promise.resolve(0).then((v) =&amp;gt; console.log(v)) // 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;has the same effect as this crazy multi-layered Promise example below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Promise.resolve(
    new Promise((resolve, _) =&amp;gt; {
        resolve(new Promise((resolve, _) =&amp;gt; {
            resolve(0)
        }))
    })
).then((v) =&amp;gt; console.log(v)) // 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4 Microtask Queue
&lt;/h3&gt;

&lt;p&gt;I said that Promises are purely a syntactic sugar, meaning that to the underlying program, chaining callbacks with Promises is the same as directly passing callbacks to functions.&lt;/p&gt;

&lt;p&gt;That's not exactly true. Consider the following 2 examples:&lt;/p&gt;

&lt;p&gt;Using Promise for passing the callback function "secondTask":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function firstTask() {
    return new Promise((resolve, reject) =&amp;gt; {
        console.log("doing the first task")
        resolve("the second task")
    })
}

function secondTask(task) {
    console.log("doing " + task)
}

function thirdTask() {
    console.log("doing the third task")
}

firstTask().then(secondTask)
thirdTask()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Directly passing in "secondTask":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function firstTask(callback) {
    console.log("doing the first task")
    callback("the second task")
}

function secondTask(task) {
    console.log("doing " + task)
}

function thirdTask() {
    console.log("doing the third task")
}

firstTask(secondTask)
thirdTask()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both examples print "doing the first task" first, but the first example prints "doing the second task" last, while the second example prints "doing the third task" last.&lt;/p&gt;

&lt;p&gt;For the second example, the execution stack is straight-forward and the order of messages generated is expected. &lt;br&gt;
We now take a look at the events happened behind the first example.&lt;/p&gt;

&lt;p&gt;1.&lt;code&gt;firstTask()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;The function call &lt;code&gt;firstTask()&lt;/code&gt; gets pushed to the call stack, which returns a Promise, hence the function passed into the Promise constructor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(resolve, reject) =&amp;gt; {
  console.log("doing the first task")
  resolve("the second task")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gets executed immediately, prints "doing the first task", and resolve the Promise.&lt;/p&gt;

&lt;p&gt;2.&lt;code&gt;.then(secondTask)&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Since the previous Promise is resolved, the callback function &lt;code&gt;secondTask&lt;/code&gt; now gets pushed to the &lt;strong&gt;Microtask Queue&lt;/strong&gt;, waiting to be executed. Now we advance to the next line &lt;code&gt;thirdTask()&lt;/code&gt;. Note that if there's more &lt;code&gt;.then()&lt;/code&gt; following this &lt;code&gt;.then(secondTask)&lt;/code&gt;, they'll all get skipped and we still continue straight to &lt;code&gt;thirdTask()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3.&lt;code&gt;thirdTask()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We print "doing the third task". &lt;br&gt;
Now the call stack is empty. The function call &lt;code&gt;secondTask()&lt;/code&gt; gets pushed to the call stack and executed, printing "doing the second task".&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Microtask Queue&lt;/strong&gt;, in comparison to the &lt;strong&gt;Event Queue&lt;/strong&gt;(aka Callback Queue), is another queue with priority higher than the event queue. When the JS call stack gets empty, before pushing tasks from the event queue, the event loop first pushes tasks from the microtask queue to the call stack, execute them all, then grab tasks from the event queue if there's any. &lt;/p&gt;

&lt;p&gt;Function execution in a Promise generated by &lt;code&gt;.then&lt;/code&gt; or &lt;code&gt;.catch&lt;/code&gt; or &lt;code&gt;.finally&lt;/code&gt; get pushed to the microtask queue.&lt;/p&gt;

&lt;p&gt;Below is a good example to show the execution priority of the call stack, the microtask queue and the event queue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// executed first
console.log("one")

// executed the last
setTimeout(() =&amp;gt; console.log("four"), 0)

// thirdly executed
Promise.resolve().then(() =&amp;gt; console.log("three"))

// secondly executed
console.log("two")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  4. Await &amp;amp; Async
&lt;/h1&gt;

&lt;p&gt;We can turn a function into async by append the keyword "async" the a function definition, but it doesn't really turn it into a non-blocking function, surprisingly. &lt;br&gt;
Consider the example below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function heavyComputation() {
    for (let i = 0; i &amp;lt; 1000000000; i++) {}
    console.log("heavy computation done")
}

console.log("before heavy computation")
heavyComputation()
console.log("after heavy computation")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although we've declared that &lt;code&gt;heavyComputation&lt;/code&gt; is async, hoping it won't block the execution of our main thread, we still have to wait for it to finish before we can run &lt;code&gt;console.log("after heavy computation")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The reason is simple enough: all the "async" keyword does is:&lt;br&gt;
&lt;strong&gt;#1&lt;/strong&gt;: Implicitly making the function return a Promise&lt;br&gt;
&lt;strong&gt;#2&lt;/strong&gt;: Allowing the use of &lt;code&gt;await&lt;/code&gt; inside the function, which is equivalent to using &lt;code&gt;.then()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To put it simple, the keywords &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; are just syntax alternatives for dealing with Promises&lt;/strong&gt;. Hence, it's not difficult to understand the behaviour of the above example, and we are able to easily understand that the two examples below are also quivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function heavyComputation() {
    return new Promise((resolve, reject) =&amp;gt; {
        for (let i = 0; i &amp;lt; 1000000000; i++) { }
        console.log("heavy computation done")
        resolve("computation result")
    })
}

function getResult(result) {
    console.log("got " + result)
}

heavyComputation().then(getResult)
console.log("main thread running...")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function heavyComputation() {
    for (let i = 0; i &amp;lt; 1000000000; i++) { }
    console.log("heavy computation done")
    return "computation result"
}

async function getResult() {
    let result = await heavyComputation()
    console.log("got " + result)
}

getResult()
console.log("main thread running...")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're thinking that the second one looks a lot cleaner, then that's exactly the point of introducing the &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; keywords: it allows us to work with Promises in a more comfortable fashion.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Working with Git: a practical guide</title>
      <dc:creator>JayZho</dc:creator>
      <pubDate>Sat, 01 Oct 2022 10:57:35 +0000</pubDate>
      <link>https://dev.to/jayzho/understanding-git-5703</link>
      <guid>https://dev.to/jayzho/understanding-git-5703</guid>
      <description>&lt;h3&gt;
  
  
  Some basic understandings
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need to well distinguish the concepts of the local repo and the remote repo. There are basically two separate repo. Each developer has their local repo, while the remote repo sitting on github acts like a single globalised repo. The interaction between a local repo and the remote repo is done via commands like &lt;code&gt;git push&lt;/code&gt;, &lt;code&gt;git fetch&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;Each branch has a HEAD, which is just a pointer to a commit that marks the tip of the branch. A branch is basically just a pointer to a commit and its commit history.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fetch vs. Pull
&lt;/h3&gt;

&lt;p&gt;To put it simple: &lt;code&gt;git pull&lt;/code&gt; = &lt;code&gt;git fetch&lt;/code&gt; + &lt;code&gt;git merge&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git fetch&lt;/code&gt; refreshes the local view of the remote repo to keep it up-to-date with all the newest changes in the remote repo. Notice the phrase "local view of the remote repo", it means that this action only let us know the current status of the remote repo, without changing(merging to) the local repo.&lt;br&gt;
To merge the changes in any of the remote branches into our local branch, do &lt;code&gt;git merge origin/&amp;lt;remote_branch&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working with branches
&lt;/h3&gt;

&lt;h4&gt;
  
  
  List all branches
&lt;/h4&gt;

&lt;p&gt;To list all local branches and the branch you're on locally: &lt;code&gt;git branch&lt;/code&gt;&lt;br&gt;
To list all remote branches: &lt;code&gt;git branch -r&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a local branch
&lt;/h4&gt;

&lt;p&gt;Create another local branch: &lt;code&gt;git branch &amp;lt;branch_name&amp;gt;&lt;/code&gt;&lt;br&gt;
Checkout to a local branch: &lt;code&gt;git checkout &amp;lt;branch_name&amp;gt;&lt;/code&gt;&lt;br&gt;
Create and checkout to a local branch: &lt;code&gt;git checkout -b &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;br&gt;
Create a branch from another local branch and checkout to it: &lt;code&gt;git checkout -b &amp;lt;new_branch&amp;gt; &amp;lt;from_branch&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Checkout to a remote branch
&lt;/h4&gt;

&lt;p&gt;For &lt;code&gt;git checkout &amp;lt;branch_name&amp;gt;&lt;/code&gt;, if there exists a remote branch with , git will &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;create a local branch with the same name as &lt;/li&gt;
&lt;li&gt;checkout to this local branch&lt;/li&gt;
&lt;li&gt;make this branch track &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The purpose of "making a branch track a remote branch" is that when using implicit commands like &lt;code&gt;git pull&lt;/code&gt;, &lt;code&gt;git push&lt;/code&gt; or &lt;code&gt;git merge&lt;/code&gt;, git knows which remote branch you're refering to. Otherwise it will say something like "no tracking information for the current branch".&lt;/p&gt;

&lt;p&gt;To set the remote branch to track, use the command&lt;br&gt;
&lt;code&gt;git branch --set-upstream-to=origin/&amp;lt;remote_branch&amp;gt; &amp;lt;local_branch&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Notice that once this is done, the command &lt;code&gt;git checkout &amp;lt;remote_branch&amp;gt;&lt;/code&gt; no longers set the local branch  to track the remote branch , instead it stays tracking the remote branch specified in the previous &lt;code&gt;--set-upstream-to&lt;/code&gt; command.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create remote branch from the local branch
&lt;/h4&gt;

&lt;p&gt;Checkout to a branch that you only have locally:&lt;br&gt;
&lt;code&gt;git checkout local1&lt;/code&gt;&lt;br&gt;
Assuming that you've commited successfully, run the command:&lt;br&gt;
&lt;code&gt;git push origin local1&lt;/code&gt;&lt;br&gt;
This will create a new remote branch named "local1", and push to it. Notice that it does not set the local branch to track the remote branch "local1".&lt;/p&gt;

&lt;h4&gt;
  
  
  Push to a different remote branch
&lt;/h4&gt;

&lt;p&gt;Say you're in local branch "local1", doing &lt;code&gt;git push origin main&lt;/code&gt; will push from local branch "main" to the remote branch "main". (So nothing to do with the branch you're currently in)&lt;br&gt;
If you wanna push from local branch "local1" to a remote branch "remote", you can do &lt;code&gt;git push origin local1:remote&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrating different works
&lt;/h3&gt;

&lt;h4&gt;
  
  
  The mechanism
&lt;/h4&gt;

&lt;p&gt;Let's say we're on a feature branch and we wanna merge the main branch into this feature branch. &lt;br&gt;
Before merging main into feature, git first determines the 3 commits that are: the base of the two branches, the tip(current commit) of branch "main", the tip(current commit) of branch "feature".&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vOPtJgCO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g64347jeiogrfj9lq3k0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vOPtJgCO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g64347jeiogrfj9lq3k0.png" alt="Image description" width="675" height="348"&gt;&lt;/a&gt;&lt;br&gt;
Then git will grab everything new from the newest commit(known as the tip) in branch "main" and chuck it into the tip of branch "feature", making this resultant repo a new commit on top of the previous commit in branch "feature".&lt;/p&gt;

&lt;p&gt;If the branch "feature" has no newer commits after the common "base" commit, git simply makes the tip of branch "main" the new merge commit of branch "feature", known as a "fast forwarding" merge commit. And yes, the tip of a branch is nothing but a pointer to a commit, so in this case, git just let the tip of branch "feature" point to the same commit as the tip of "main", making this the "new" merge commit as the result of &lt;code&gt;git merge feature main&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Merge from a branch
&lt;/h4&gt;

&lt;p&gt;If you're already on branch A, then to merge branch B into branch A: &lt;code&gt;git merge &amp;lt;branch_B&amp;gt;&lt;/code&gt;&lt;br&gt;
Merge 2 branches explicitly: &lt;code&gt;git merge &amp;lt;receiving_branch&amp;gt; &amp;lt;incoming_branch&amp;gt;&lt;/code&gt;&lt;br&gt;
If the merge results in a conflict and you wanna abandon this merge action and roll back to the state before this merge, do &lt;code&gt;git reset --hard HEAD&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rebase to a branch
&lt;/h4&gt;

&lt;p&gt;Rebase moves all the commits in one branch on top of another branch, making a single-line commit history. This is another technique used in merging different commits, and has advantages over &lt;code&gt;git merge&lt;/code&gt; in the sense that it creates a linear branch history instead.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
    </item>
    <item>
      <title>Computer Networking: Intuitive Understanding of the Basics (updating...)</title>
      <dc:creator>JayZho</dc:creator>
      <pubDate>Fri, 30 Sep 2022 13:29:24 +0000</pubDate>
      <link>https://dev.to/jayzho/computer-networking-thoughts-3pc7</link>
      <guid>https://dev.to/jayzho/computer-networking-thoughts-3pc7</guid>
      <description>&lt;h2&gt;
  
  
  The 5-Layer Model
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Application layer&lt;/strong&gt;: Defines the meaning of the message. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;should we include the length of the message in bytes? &lt;/li&gt;
&lt;li&gt;should we define a set of message types to indicate the purpose of the message? Something like "POST" and "GET" in HTTP&lt;/li&gt;
&lt;li&gt;what Transport layer protocol should we choose? Do we care about the reliability a lot? Maybe UDP will do the job(instead of TCP) if missing packets are acceptable?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Transport layer&lt;/strong&gt;: Defines the mechanism of the communication. Still programmable by software layer. For example, instead of using TCP, we could use the socket library in Python to totally implement our own transport layer protocol and apply it to both the client and server side to make it work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network layer&lt;/strong&gt;: Defines the bigger picture of the network, in comparison to the Link Layer. Each IP address represents the entry to a local network, but the inside of each local area network is a black box for the Network Layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  SSL (Secure socket layer)
&lt;/h2&gt;

&lt;p&gt;Without any protection, the TCP layer transfers the message in cleartext, which could be dangerous. If you're interested enough, you could actually implement your own "SSL" by building a software that accepts data from the application layer, encoding it and passing it to TCP, on the receiving side simply do the opposite. By inserting this piece of software between the application layer and the TCP layer, you've got your own "SSL".&lt;br&gt;
That's basically how SSL works and what SSL is.&lt;br&gt;
HTTPS is an example that uses SSL to securely transfer data on top of traditional HTTP messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cookie
&lt;/h2&gt;

&lt;p&gt;Just a user profile created and stored on the server side:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sam visits Amazon.com via his browser for the first time&lt;/li&gt;
&lt;li&gt;Amazon's server: "Hey, a new guy is visiting us, let's create a profile for him with the unique identifier 'Sam001'". Then the server passes "cookie: Sam001" together with other response data back to the browser.&lt;/li&gt;
&lt;li&gt;The browser: "Oh, I see a cookie header, let's store it onto the computer so every following request to Amazon.com we'll include this cookie, then the server knows it's us and it'll give us customised content!"&lt;/li&gt;
&lt;li&gt;Sam continues browsing on Amazon.com, meanwhile the server tracks his activities like what types of products he's interested in, etc, storing this info in his profile on the server side.&lt;/li&gt;
&lt;li&gt;A week later, Sam visits Amazon.com on his computer again. The browser sends the request with his cookie to the server.&lt;/li&gt;
&lt;li&gt;Amazon's server: "Hey it's Sam001, according to our record in his profile here, he likes gaming a lot, let's send him some ads about our gaming product"&lt;/li&gt;
&lt;li&gt;Sam sees gaming product on Amazon's site, wondering how they know him so well and spend his money recklessly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Web Cache
&lt;/h2&gt;

&lt;p&gt;Just a proxy server normally installed by ISPs on their access points.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A client requests for object "loneliness.com/hotgirl.png"&lt;/li&gt;
&lt;li&gt;The browser sends the request to a web cache server instead of the origin server.&lt;/li&gt;
&lt;li&gt;The web cache server checks if it has "loneliness.com/hotgirl.png" cached, if so it simply returns it to the browser; otherwise it requests the origin server, gets the object, cache it and also sends it back to the browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that some content might be outdated if cached for a relatively long time. &lt;br&gt;
In this case, the &lt;code&gt;Last-Modified: Wed, 7 Sep 2011 09:23:24&lt;/code&gt; header in a response HTTP message would be used, and the next time a browser requests for the same object, the web caches server sends a requests to the origin server including &lt;code&gt;If-modified-since: Wed, 7 Sep 2011 09:23:24&lt;/code&gt;. If it hasn't been modified on the origin server, it responses with &lt;code&gt;304 Not Modified&lt;/code&gt; with an empty body(saving some bandwidth), and the web cache is now reassured and happliy sends the cached content back to the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS (Domain Name Service)
&lt;/h2&gt;

&lt;p&gt;Just a translation from a human-prefered hostname to a computer-prefered IP address.&lt;/p&gt;

&lt;p&gt;The process works as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You visit "&lt;a href="http://www.amazon.com.au"&gt;www.amazon.com.au&lt;/a&gt;" on your browser&lt;/li&gt;
&lt;li&gt;Before sending the request to Amazon's server, the browser first extract the domain name "&lt;a href="http://www.amazon.com.au"&gt;www.amazon.com.au&lt;/a&gt;" and send it to the DNS software installed in the browser.&lt;/li&gt;
&lt;li&gt;The DNS software(client side) sends the domain name over UDP
to a DNS server. This DNS server is normally a local DNS server employed by your ISP or institution, sitting in the network somewhere very close to your LAN.&lt;/li&gt;
&lt;li&gt;The local DNS server now queries other DNS server(s) and eventually get back the IP address(es) for "&lt;a href="http://www.amazon.com.au"&gt;www.amazon.com.au&lt;/a&gt;" and return it back to the DNS client software on your browser, which further give to back to your browser and your browser can now initiate a TCP connection with the server at that IP address and start the HTTP communication. Remember that if this "domain name" -&amp;gt; "IP" mapping happens to be cached in the local DNS server, it will immediately return it to your browser without the need to further querying other DNS servers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that the process of querying other DNS servers to get the desired IP address is a bit more complicated than this, below is a brief discussion if you're interested:&lt;/p&gt;

&lt;p&gt;The process of finding an IP address according to a domain name like "&lt;a href="http://www.amazon.com"&gt;www.amazon.com&lt;/a&gt;" is typically an iterative process: &lt;/p&gt;

&lt;p&gt;Since it's far too much data for storing all the "complete domain name" -&amp;gt; "IP address(es)" mappings, the DNS servers work in a distributed manner, each responsible for a (part of) certain hierarchy in the domain name. Intuitively, the highest tier domain like &lt;code&gt;.com&lt;/code&gt; &lt;code&gt;.net&lt;/code&gt; &lt;code&gt;.edu&lt;/code&gt; don't have too many variations, hence there are not so many root level DNS servers globally in comparison to the number of DNS servers for lower levels. &lt;/p&gt;

&lt;p&gt;When given a domain name to lookup at a local DNS server, the local DNS server first queries a root DNS server for the address of the next level DNS server. In this case, say "somedns.edu" is responsible for looking up all domain names ending with &lt;code&gt;.com&lt;/code&gt;, then the root DNS server will pass back "somedns.edu" to the local DNS server, then the local DNS server further queries "somedns.edu", and "somedns.edu" sees that it's "(www)&lt;strong&gt;.amazon&lt;/strong&gt;(.com)", grabs an address in its record which is responsible for return the IP address for "*.amazon", and ... you get the idea.&lt;/p&gt;

&lt;p&gt;Note that DNS servers could be widely used for load balancing purposes, since popular websites like Amazon has many servers all over the globe, when return the IP address for something like "amazon.com.au", the DNS server probably would have multiple valid IP addresses. What it does is that it rotates the list of all available IP addresses for Amazon servers every time a browser queries it, and since the browser normally would request for the first IP address it's given, this helps balacing the server's work load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding IP Addresses (Network Layer)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;the home router (with NAT) doesn't look like a router to the outside networks, it simply looks like a device with a single interface(IP address) receiving and sending IP datagrams.&lt;/li&gt;
&lt;li&gt;NAT is basically mapping (endDeviceIPAddressWithinTheSubnet, endDevicePortNum) to (publicIPAddressOfTheHomeRouter, homeRouterPortNum) &lt;/li&gt;
&lt;li&gt;IP address is per interface, rather than per device.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding MAC Addresses (Link Layer)
&lt;/h2&gt;

</description>
      <category>networks</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>An Intro to Linux</title>
      <dc:creator>JayZho</dc:creator>
      <pubDate>Thu, 29 Sep 2022 06:39:25 +0000</pubDate>
      <link>https://dev.to/jayzho/an-intro-to-linux-1jmo</link>
      <guid>https://dev.to/jayzho/an-intro-to-linux-1jmo</guid>
      <description>&lt;h2&gt;
  
  
  Users and Permissions
&lt;/h2&gt;

&lt;p&gt;For each file, &lt;code&gt;ls &amp;lt;filename&amp;gt; -l&lt;/code&gt; displays the permission of the file, something like &lt;code&gt;-rw-rw-r--&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the first char specifies the type of file: d for directory, - for file, l for link.&lt;/li&gt;
&lt;li&gt;every following 3 chars specify the permissions to 3 different groups respectively: &lt;strong&gt;the file owner, the group and others&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The purpose of having these 3 different tiers&lt;/strong&gt; for each file could be explained easily with an example:&lt;br&gt;
You(t1) and your teammates(t3, t2) are working on a project, and you and your teammates and other random people are all using the same Linux machine in the school lab. You wanna give yourself the permission to read, write and execute the program "project.py", while giving your teammates the rights to read and execute but not modifying it, and you don't even allow others to look at your code. &lt;br&gt;
Then what you could do is to create a group named "team", putting t1, t2 and t3 all under this group, then do &lt;code&gt;chmod 750 project.py&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing permissions
&lt;/h2&gt;

&lt;p&gt;Only the file owner or the root user is able to change the permissions of a file. Three commands are used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;chmod &amp;lt;xxx&amp;gt;&lt;/code&gt; changes the permissions of the file, where each x corresponds to the permissions to the file owner, group and others respectively. Note that the numbers are: r:4, w:2, x:1&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chgrp &amp;lt;group_name&amp;gt; &amp;lt;file_name&amp;gt;&lt;/code&gt; changes the group. Note that
&lt;code&gt;&amp;lt;group_name&amp;gt;&lt;/code&gt; must be an existing group in /etc/group&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chown&lt;/code&gt;changes the owner of the file. I've never used it though.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  $PATH
&lt;/h2&gt;

&lt;p&gt;This variable stores all the paths that are looked up when executing a command. For example, the command &lt;code&gt;ls&lt;/code&gt; is stored under &lt;code&gt;/bin/&lt;/code&gt;.&lt;br&gt;
To inspect the vairable, do &lt;code&gt;echo $PATH&lt;/code&gt;&lt;br&gt;
To add something to the $PATH variable, do &lt;code&gt;PATH="${PATH}:&amp;lt;absolute_path&amp;gt;"&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspecting files
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;cat &amp;lt;filename&amp;gt;&lt;/code&gt;: print the content of the file&lt;br&gt;
&lt;code&gt;more &amp;lt;filename&amp;gt;&lt;/code&gt;: display the file page by page. Press &lt;strong&gt;space&lt;/strong&gt; for next page, press &lt;strong&gt;q&lt;/strong&gt; for quit, press &lt;strong&gt;Enter&lt;/strong&gt; for next line.&lt;br&gt;
&lt;code&gt;head -&amp;lt;n&amp;gt; &amp;lt;filename&amp;gt;&lt;/code&gt;: display the first n lines of the file&lt;br&gt;
&lt;code&gt;tail -&amp;lt;n&amp;gt; &amp;lt;filename&amp;gt;&lt;/code&gt;: display the last n lines of the file&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>An Introduction to Database</title>
      <dc:creator>JayZho</dc:creator>
      <pubDate>Wed, 28 Sep 2022 11:09:46 +0000</pubDate>
      <link>https://dev.to/jayzho/an-introduction-to-database-1hmk</link>
      <guid>https://dev.to/jayzho/an-introduction-to-database-1hmk</guid>
      <description>&lt;h2&gt;
  
  
  Background knowledge
&lt;/h2&gt;

&lt;p&gt;Database - an organised collection of information, normally stored on a computer electronically.&lt;/p&gt;

&lt;p&gt;DBMS - database management system, which is a piece of software that sits between the layer of database and users to allow efficient interaction with the database(querying, updating, deleting, etc), using a programming language such as SQL.&lt;/p&gt;

&lt;p&gt;RDBMS - relational database management system, a subset of DBMS that uses tables of rows and columns to organise data.&lt;/p&gt;

&lt;p&gt;SQL - a programming language that interacts with relational DBMS such as MySQL and PostgreSQL. Note that the SQL used for one RDBMS is not always protable to any other RDBMS without modification. SQL is actually a combination of 4 types of query language: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query language: to query&lt;/li&gt;
&lt;li&gt;Definition language: to define database schemas&lt;/li&gt;
&lt;li&gt;Control language: to do things like user permission management&lt;/li&gt;
&lt;li&gt;Manipulation language: like CRUD&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NoSQL - Non-relational Database. Rather than tables, NRDBMS store data in a more flexible way, such as key-value pairs, JSON, etc. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is an embedded/serverless database?
&lt;/h2&gt;

&lt;p&gt;Many database uses the client-server mechanism, meaning that the DBMS is running as a server and it waits for request over the internet/locally from another software to manipulate the database and sends back the data accordingly.&lt;br&gt;
An embedded database on the other hand, is integrated into the software itself, meaning that the software that wants to interact with the database will have the DBMS as part of its program.&lt;br&gt;
A good example would be MySQL vs. sqlite, both of which are relational DBMS by the way.&lt;/p&gt;
&lt;h2&gt;
  
  
  Keys in RDBMS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Primary key&lt;/strong&gt; - unique key for each entry&lt;br&gt;
&lt;strong&gt;Composite key&lt;/strong&gt; - multiple fields together to make up a unique key&lt;br&gt;
&lt;strong&gt;Foreign key&lt;/strong&gt; - a key linking to another table which acts as the primary key in that table&lt;br&gt;
&lt;strong&gt;Secondary key&lt;/strong&gt; - any primary key candidates that are not selected as the primary key. For example, for the table "student", "email", "student_id" and "phone_number" could all be the primary key, but when "student_id" is selected as the primary key, "email" and "phone_number" become the secondary keys for this table.&lt;br&gt;
&lt;strong&gt;Partial key&lt;/strong&gt; - one or more fields of a weak entity, which uniquely identifies the weak entity when given its own er entity(strong entity). For example, for "Building"(strong entity) has many "Room"(weak entity), the attribute "room_number" could be used as partial key of "Room", since a building cannot have more than 1 room with the same room number. However, attribute like "area" cannot be partial key, since a building can have multiple rooms of the same area.&lt;/p&gt;
&lt;h2&gt;
  
  
  From ER diagram to Database schema
&lt;/h2&gt;

&lt;p&gt;Basically there's 2 types of tables created from an ER diagram:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Entity Table. Student, Employee, etc.&lt;/li&gt;
&lt;li&gt;Relation Table. Superviser, Employment, etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Strong entity
&lt;/h4&gt;

&lt;p&gt;Mapping an entity to an entity table is straight forward. &lt;/p&gt;
&lt;h4&gt;
  
  
  Weak entity
&lt;/h4&gt;

&lt;p&gt;Create a separate realtion table. Include all weak entity's attributes plus the owner's primary key.&lt;/p&gt;
&lt;h4&gt;
  
  
  1 to ... relationship
&lt;/h4&gt;

&lt;p&gt;If "A can have 1 or 0 B", "B can have 0 ... many A", then create foreign key on A's table, pointing to table B. Favor the total participation as this guarantees un-nullable field.&lt;/p&gt;
&lt;h4&gt;
  
  
  Many to many relationship
&lt;/h4&gt;

&lt;p&gt;Create a separate relation table.&lt;/p&gt;
&lt;h2&gt;
  
  
  SQL Basics
&lt;/h2&gt;
&lt;h4&gt;
  
  
  Create/Delete/Alter table
&lt;/h4&gt;

&lt;p&gt;Create a table called "student":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE student (
    student_id INT PRIMARY KEY,
    name VARCHAR(20) NOT NULL,
    major VARCHAR(28),
    degree_id INT,
    FOREIGN KEY(degree_id) REFERENCES degree(degree_id) ON DELETE CASCADE,
);

CREATE TABLE degree (
    degree_id INT PRIMARY KEY,
    name VARCHAR(30) NOT NULL,
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete the table "student":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DROP TABLE student;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop the column "major":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE student DROP COLUMN major;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a column "gpa", which has 3 digits and 2 of them are decimals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE student ADD gpa DECIMAL(3, 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Insert/Update/Delete
&lt;/h4&gt;

&lt;p&gt;Insert all 3 fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO student VALUES(5211225, "Shane", "COMP");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Insert only the specified fields: note that "name" cannot be null by the constraints defined before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO student(student_id, name) VALUES(5211225, "Shane");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update all major "Biology" to "Bio":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UPDATE student
SET major = "Bio"
WHERE major = "Biology"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete a specific entry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DELETE FROM student
WHERE student_id = 5;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Querying
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM student
WHERE major = "Chemistry" OR name IN ("Claire", "Ben")
ORDER BY major
LIMIT 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Redundency &amp;amp; Normalisation
&lt;/h2&gt;

&lt;h4&gt;
  
  
  What is redundency in a database schema?
&lt;/h4&gt;

&lt;p&gt;Redundency could be a problem in the sense that it harms the consistency between updates. On the other hand, it could be benificial since it improves the performance by avoiding some "JOIN"s between tables.&lt;br&gt;
The redundency in a database schema and its inconsistency problem has similarity to some bad code: Say you have some code that depends on another computation "plus two", and you use this dependent computation twice in this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// first time
a = a + 2;

// some other code ...

// second time
a = a + 2;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you decide to change the "plus two" computation to "times two", you have to change everywhere that you wrote this code. (twice in this case). This can easily lead to inconsistency problem.&lt;br&gt;
A better and fairly obviously practice is to write the "plus two" logic as a separate function and calls this function when needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function dependentComputation(x) {
    return x + 2
}
// use the logic
a = dependentComputation(a)

// use it again somewhere else
a = dependentComputation(a)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later on when you have to change the computation, simply change it in the function and it automatically updates all the places it was refered to. &lt;/p&gt;

&lt;p&gt;This is similar to how we get rid of the redundency in a database schema. Say two entries share the same third entity "account" in a table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;order_id | order_total | account_id | account_balance
0001       18.00         8888         20.00
0002       12.00         8888         20.00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a new order is placed and added to this table, we have to update all other entries related to account "8888", otherwise inconsistent account balance would occur:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;order_id | order_total | account_id | account_balance
0001       18.00         8888         20.00  &amp;lt;- INCORRECT BALANCE
0002       12.00         8888         20.00  &amp;lt;- INCORRECT BALANCE
0003       6.00          8888         14.00  &amp;lt;- ACTUAL BALANCE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now just like how we extracted the computation logic into a separate function in the previous example, we now extract the "account related" fields into a separate table, and just add a foreign key pointing to the account table in each entry in the "order" table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ORDER TABLE:
order_id | order_total | account_id
0001       18.00         8888         
0002       12.00         8888         
0003       6.00          8888         

ACCOUNT TABLE:
acc_id   | acc_balance
8888       14.00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Functional Dependency
&lt;/h4&gt;

&lt;p&gt;For a table with attributes A, B, C, D:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A  | B  | C  | D
a1   b1   c1   d1
a2   b2   c2   d2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If knowing an attribute X determines the uniqueness of another attribute Y, then we say &lt;strong&gt;X determines Y&lt;/strong&gt;, or &lt;strong&gt;Y is functionally dependent on X&lt;/strong&gt;, denoted as &lt;strong&gt;X -&amp;gt; Y&lt;/strong&gt;.&lt;br&gt;
If the combination of some attributes is unique, say A and B together determines C or D, then we say &lt;strong&gt;AB -&amp;gt; CD&lt;/strong&gt;.&lt;br&gt;
Intuitively, a primary key or secondary key determines any other attributes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Dependency Closure
&lt;/h4&gt;

&lt;p&gt;The dependency closure of an attribute X in the table ABCD... is the set of attributes {ABCD...} that are derivable from X.&lt;/p&gt;

&lt;h4&gt;
  
  
  Normal Form
&lt;/h4&gt;

&lt;p&gt;BCNF (Boyce Codd Normal Form):&lt;br&gt;
If any functional dependency "X -&amp;gt; Y" in the schema satisfies that "X contains the whole key", then the schema is in BCNF. Notice that if X only contains a candidate key but not the primary key, it's still in BCNF.&lt;/p&gt;

&lt;p&gt;The decomposition step to achieve BCNF regarding a functional dependency "X -&amp;gt; Y" in the table S is fairly straight forward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove Y from table S&lt;/li&gt;
&lt;li&gt;Create a new table "XY".&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Working with Arrays in React (updating)</title>
      <dc:creator>JayZho</dc:creator>
      <pubDate>Wed, 21 Sep 2022 09:30:55 +0000</pubDate>
      <link>https://dev.to/jayzho/working-with-arrays-in-react-3m7a</link>
      <guid>https://dev.to/jayzho/working-with-arrays-in-react-3m7a</guid>
      <description>&lt;h2&gt;
  
  
  Mapping to a list of components
&lt;/h2&gt;

&lt;p&gt;Say we got an array of fruits, and we'd like to render each as a fruit card in the page, then we can use &lt;code&gt;.map&lt;/code&gt; as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let fruits = ["apple", "banana", "peach"]
return (
  { fruits.map(x =&amp;gt; &amp;lt;FruitCard name={x}&amp;gt;) }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But React may warn you that "&lt;strong&gt;Each child in a list should have a unique "key" prop&lt;/strong&gt;". And the reason is as follow:&lt;/p&gt;

&lt;p&gt;Say we initially had a list of fruits as ["apple", "banana"], and we mapped and rendered them as 2 individual &lt;code&gt;&amp;lt;FruitCard&amp;gt;&lt;/code&gt; components in the page. &lt;/p&gt;

&lt;p&gt;Later on, when we need to add one more fruit "peach" and update the page to display this third &lt;code&gt;&amp;lt;FruitCard&amp;gt;&lt;/code&gt;, without the "key" prop, React actually has no idea about which fruits are newly added/deleted or which have stayed unchanged, hence it has no choice but to remove the previous 2  elements from the DOM tree and create a new element for each child of the updated list and add them to the DOM tree all over again.&lt;/p&gt;

&lt;p&gt;To avoid this inefficient DOM update, React requires us to give each child a unique ID, then later when the list is updated, React only updates the ones that are changed according to their ID. In the example above, we could do something like: (assuming each fruit has its unique name)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
  { fruits.map(x =&amp;gt; &amp;lt;FruitCard name={x} key={x}&amp;gt;) }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, when "peach" is added, React knows that "apple" and "banana" were the old elements that are untouched, hence it only adds a new element for "peach" into the DOM tree, saving the work to remove and re-add the other 2 old elements.&lt;/p&gt;

&lt;p&gt;In short, &lt;strong&gt;the "key" prop is to allow React to keep track of the list elements, therefore improving the performance on re-rendering&lt;/strong&gt;. &lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>array</category>
    </item>
    <item>
      <title>Frontend Notes</title>
      <dc:creator>JayZho</dc:creator>
      <pubDate>Thu, 15 Sep 2022 07:14:18 +0000</pubDate>
      <link>https://dev.to/jayzho/frontend-notes-4ii0</link>
      <guid>https://dev.to/jayzho/frontend-notes-4ii0</guid>
      <description>&lt;h1&gt;
  
  
  HTML
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Some interesting tags
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;: link to another web page&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;: link text to an input, so when clicked it was as if the input is clicked&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;: another html page within the current html page&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt;: plays music in your page&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt;: monospace for letters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt;: take tabs and spaces into accounts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;, etc.: semantic tags rather than functional tags. But search engines like Google or web scrapers would grab info from tags like this and understand the web better.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt;: describes the meta data of the web page. Like page description, image, favicon, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;meta name="viewport" content="width=device-width"&amp;gt;&lt;/code&gt; sets viewport size to the actual size of the device, rather than auto zooming out. (especially for mobile devices)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;meta name="viewport" content="initial-scale=1.0, ..."&amp;gt;&lt;/code&gt; tells how much we can zoom in/out.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt;: defines what shows up when JS is disabled for the web.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt;: embeds media (like a youtube video) into the web page. The main difference from an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; is that &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; is used to embed an entire html page while this is for media components.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Images
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Raster image vs. Vector image
&lt;/h4&gt;

&lt;p&gt;A raster images stores a 2D array of colours, gets blurry when magnified; while a vector image stores the geometry of the image instead.&lt;/p&gt;

&lt;h4&gt;
  
  
  JPG (raster)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;24 bits per colour (more bits means more colour options)&lt;/li&gt;
&lt;li&gt;Lossy compression (JPG encoded when storing and decoded when displaying, but can lose original info after decoding)&lt;/li&gt;
&lt;li&gt;Suitable for high resolution photos&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  PNG (raster)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;16 - 24 bits per colour&lt;/li&gt;
&lt;li&gt;Lossless compression&lt;/li&gt;
&lt;li&gt;Suitable mostly for non-photo use cases (when subtles details matter)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Base64 encoding
&lt;/h4&gt;

&lt;p&gt;A binary-to-text encoding scheme to convert binary data to an ASCII string.&lt;br&gt;
A common application is to represent image directly in the &lt;code&gt;&amp;lt;img src="..." /&amp;gt;&lt;/code&gt; tag, which stores the image's data as part of the html, reducing the request to further retrieve that image data from an URI. This is a common technique for loading small image files.&lt;/p&gt;

&lt;h1&gt;
  
  
  CSS
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Combinators
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;.B .C&lt;/code&gt; all .C that are inside .B&lt;br&gt;
&lt;code&gt;.B &amp;gt; .C&lt;/code&gt; all .C that are direct child of .B&lt;br&gt;
&lt;code&gt;.B + .C&lt;/code&gt; sibing .C that follows immediately after .C&lt;br&gt;
&lt;code&gt;.B ~ .C&lt;/code&gt; all sibings .C that follows after .C&lt;/p&gt;

&lt;h3&gt;
  
  
  Pseudo classes
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;selector&amp;gt;:&amp;lt;pseudo-class&amp;gt;&lt;/code&gt;: select the elements with a special state.&lt;br&gt;
e.g. &lt;code&gt;button:hover&lt;/code&gt; &lt;code&gt;div:first-child&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pseudo elements
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;selector&amp;gt;::&amp;lt;pseudo-element&amp;gt;&lt;/code&gt;: create content for the selected elements or style part of the elements.&lt;br&gt;
e.g. &lt;code&gt;p::after { content: "."; color: red; }&lt;/code&gt; appends a red "." after every &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; element&lt;/p&gt;

&lt;h3&gt;
  
  
  Specificity
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;!important&lt;/code&gt; &amp;gt; inline style &amp;gt; id &amp;gt; class &amp;gt; type&lt;/p&gt;

&lt;h3&gt;
  
  
  Inline vs. Block elements
&lt;/h3&gt;

&lt;p&gt;Inline elements(like &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;) takes only the width of its content, while block elements(like &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;) takes up the whole line, resulting in a newline for every element.&lt;/p&gt;

&lt;h3&gt;
  
  
  Grid layout
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;{display: grid}&lt;/code&gt;: Just another useful layout I don't use very often. Use it when necessary then!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>css</category>
    </item>
    <item>
      <title>A poor introduction to compilers.(still updating)</title>
      <dc:creator>JayZho</dc:creator>
      <pubDate>Sat, 07 May 2022 02:21:45 +0000</pubDate>
      <link>https://dev.to/jayzho/a-bad-introduction-to-compiler-5bic</link>
      <guid>https://dev.to/jayzho/a-bad-introduction-to-compiler-5bic</guid>
      <description>&lt;h2&gt;
  
  
  What is a compiler
&lt;/h2&gt;

&lt;p&gt;The job of a compiler is to turn source code that's written by humans:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int i = 0;
i = 10 + 20;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into machine code(a bunch of 0s and 1s) that's understood by computers in order to run the program: (say, 8-bit instructions)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;01110010
01010111
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usually, the compilation process involves converting the source code into intermediate code called &lt;strong&gt;Assembly Code&lt;/strong&gt; first, then further turning the assembly code into machine code. &lt;br&gt;
The second step is relatively straight forward as it's mostly just a 1-to-1 replacement from assembly instruction to its binary representation.&lt;br&gt;
This blog is largely about how we go from source code to assembly code.&lt;/p&gt;
&lt;h2&gt;
  
  
  From Source Code to Assembly
&lt;/h2&gt;

&lt;p&gt;The big picture of this process is as shown below:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qF7fanRz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pobv36cjv2w70wc5movj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qF7fanRz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pobv36cjv2w70wc5movj.png" alt="Image description" width="880" height="882"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step1: Lexical Analysis
&lt;/h3&gt;
&lt;h5&gt;
  
  
  -- turn the source code into a bunch of tokens.
&lt;/h5&gt;

&lt;p&gt;In order to discuss lexical analysis, we should first have a look at what a programming language formally is.&lt;/p&gt;

&lt;p&gt;Very much like natural languages(e.g. English), a programming language is just a set of strings(called "&lt;strong&gt;tokens&lt;/strong&gt;"), where each string/token is a sequence of symbols allowed in this programming language.&lt;br&gt;
For example, in English, the set of allowed symbols are roughly the 26 alphabets plus the standard English punctuation. Therefore,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How are you?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;is a valid English sentence, while&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;H@w are you?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;isn't, since "@" isn't a valid symbol defined in the language.&lt;/p&gt;

&lt;p&gt;A programming language normally consists of 5 kinds of tokens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identifiers&lt;/strong&gt;: variable names, function names are both identifiers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keywords&lt;/strong&gt;: reserved words such as "if", "while" and "return".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operators&lt;/strong&gt;: +, -, &amp;lt;, &amp;gt;, &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separators&lt;/strong&gt;: brackets, comma and semicolon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Literals&lt;/strong&gt;: source representation of a value&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The job of this lexical analysis step is to scan through the source code and produce a set of tokens. For example, for a program that only has one line of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int a = 0;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The list of tokens produced after lexical analysis would be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  Keyword("int"),
  Identifier("a"),
  Operator("="),
  Literal("0"),
  Separator(";")
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step2: Syntax Analysis
&lt;/h3&gt;

&lt;h5&gt;
  
  
  -- given a list of tokens, build a tree to represent the structure of this program.
&lt;/h5&gt;

&lt;p&gt;In order for a sentence to make sense, it must be both **syntactically **and **semantically **correct. The syntax of a program deals with the program structure, while the semantics of a program deals with the program logic. &lt;br&gt;
For example, the following sentence would be considered syntactically incorrect in general:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tom likes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;since the verb "like" is missing its object. &lt;br&gt;
A sentence could also be syntactically correct while being semantically incorrect. The sentence&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tom sees sounds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;obviously doesn't make sense, but it's syntactically correct as it consists of the subject, the verb and the object of a sentence.&lt;/p&gt;

&lt;p&gt;The syntax rules of a language are called "Grammar", which defines what the structure of a language could be.&lt;/p&gt;

</description>
      <category>compiler</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
