<?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>Forem: Ed</title>
    <description>The latest articles on Forem by Ed (@skepticalhippoh).</description>
    <link>https://forem.com/skepticalhippoh</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%2F13828%2F92b651bb-8cc2-43de-b3da-926a9857c9ee.png</url>
      <title>Forem: Ed</title>
      <link>https://forem.com/skepticalhippoh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/skepticalhippoh"/>
    <language>en</language>
    <item>
      <title>The Unarchitecture</title>
      <dc:creator>Ed</dc:creator>
      <pubDate>Thu, 18 Feb 2021 13:22:51 +0000</pubDate>
      <link>https://forem.com/skepticalhippoh/the-unarchitecture-3j2n</link>
      <guid>https://forem.com/skepticalhippoh/the-unarchitecture-3j2n</guid>
      <description>&lt;p&gt;A team of developers have been given a new greenfield project to deliver. The powers that be told them they have full control over the technical direction of the project. The team was excited to move on from their legacy project, it was a great opportunity for them to apply the lessons from the old onto the new. They were going to &lt;em&gt;do things properly&lt;/em&gt; this time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Barn With a Golden Hammer
&lt;/h2&gt;

&lt;p&gt;One of the developers closely follows the &lt;a href="https://eng.uber.com/" rel="noopener noreferrer"&gt;Uber Engineering Blog&lt;/a&gt; and there she read Uber uses Golang to hit stellar RPS (requests per second) numbers. She proposed that the team writes this project in Golang so they can leverage that same performance.&lt;/p&gt;

&lt;p&gt;The second developer suggested they use React for the frontend and build an SPA (single page application), because that's what everyone's doing these days and it's the de facto standard.&lt;/p&gt;

&lt;p&gt;The last developer found great success with serverless microservices at his previous company. He recommended they leverage the near infinite scalability of the serverless platform for their new project.&lt;/p&gt;

&lt;p&gt;At face value, the plan seemed solid - Golang on the backend, a React SPA on the frontend and it's all going to be served by a serverless microservice infrastructure. It was going to be performant, infinitely scalable and decoupled.&lt;/p&gt;

&lt;p&gt;Executing the plan proved more difficult than they anticipated. It turns out they forgot to take a few things into account.&lt;/p&gt;

&lt;p&gt;The team didn't have any real experience with Golang as they were all primarily PHP developers. Building a React SPA was proving to be a time sink as they now had an additional problem of communicating with APIs. By the time they had 12 microservices, the complexity of their system was causing more issues than it was solving. To add insult to injury, they were only asked to build a very basic inventory management system for internal use.&lt;/p&gt;

&lt;p&gt;Somewhere in the excitement and the prospect of doing it like the big companies the team forgot where they were, what worked for them and what they were building. What they thought they had was a solid architectural foundation to build upon, but what they ended up with was an &lt;em&gt;unarchitecture&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Exactly is Unarchitecture?
&lt;/h2&gt;

&lt;p&gt;I actually borrowed the idea for the word from &lt;a href="https://unarchitecture.wordpress.com/about/" rel="noopener noreferrer"&gt;this blog&lt;/a&gt; and think it encompasses what I'm trying to convey here. To me, unarchitecture is ill-fitting software architecture, which is often born of best intentions.&lt;/p&gt;

&lt;p&gt;If good software architecture makes a codebase easy and enjoyable to work with, then unarchitecture is the antithesis of that. An unarchitected codebase is a source of endless friction and misery for developers, it makes new features tiresome to develop and fixing bugs a soul-crushing exercise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where and How Does it Happen?
&lt;/h2&gt;

&lt;p&gt;The story in the introduction has a series of questionable decisions that led to unarchitecting the codebase, but in reality all it takes is just one decision to create a pocket of friction in any codebase. For example, you could just over-engineer the CI pipeline and make nobody on your team want to touch it with a 10 foot pole.&lt;/p&gt;

&lt;p&gt;I've found that unarchitecture often comes from a good place. We often tend to apply what we already know as working without really weighing up the pros and cons (everything has cons) of the approaches within our current context. What worked for a company with a team of 20 might not necessarily work for a team of 3. This applies across the board to software packages, languages, libraries, frameworks and patterns.&lt;/p&gt;

&lt;p&gt;I like to think it's akin to wearing your parents shoes when you're 7. You've seen your parents walk in them and you really want to be like the grown ups, but once you try them on you can barely walk in them, much less run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preventing Unarchitecture
&lt;/h2&gt;

&lt;p&gt;I think there are a few ways we can try and prevent ourselves from unarchitecting our applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We should aim to try and keep things as simple as possible for as long as possible. Introduce complexity only when we really need it.&lt;/li&gt;
&lt;li&gt;Put our ego aside and question whether the pattern or technology we're applying is right for us, within our current context. Some questions that I like to ask myself are:

&lt;ul&gt;
&lt;li&gt;Will my team realistically be able to maintain this? Do we have the skills required currently, can we learn or grow the team to accommodate for what we're trying to achieve?&lt;/li&gt;
&lt;li&gt;Can it stifle future growth? If we're going for simplicity, will it be hard to evolve if we need to?&lt;/li&gt;
&lt;li&gt;If our decision turns out being a mistake, how hard will it be to take a step back and go on a different path?&lt;/li&gt;
&lt;li&gt;Is this something that will bring us value? How? Maybe our efforts are better focused elsewhere?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;I'm a big believer in &lt;a href="https://www.thoughtworks.com/insights/blog/applying-conways-law-improve-your-software-development" rel="noopener noreferrer"&gt;Conway's Law&lt;/a&gt; and think we should take into account the structure of the organisation when we're architecting our applications. Our architecture should either complement the structure or drive change in the direction that we want to go.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing Note
&lt;/h2&gt;

&lt;p&gt;In a world where microservices, serverless, Leviathan-esque container orchestration tools and decoupled frontends are all the rage, it's easy to lose sight of where we are and what we're trying to achieve and give in to hype driven development instead.&lt;/p&gt;

&lt;p&gt;I think, in general, we should just strive to approach software architecture with more pragmatism and not give in to dogma. After all, there's no such thing as a panacea.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>webdev</category>
      <category>design</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Notes on Promises and Useful Snippets (ft. async and await)</title>
      <dc:creator>Ed</dc:creator>
      <pubDate>Sun, 03 Jan 2021 19:06:00 +0000</pubDate>
      <link>https://forem.com/skepticalhippoh/notes-on-promises-and-useful-snippets-ft-async-and-await-3h7b</link>
      <guid>https://forem.com/skepticalhippoh/notes-on-promises-and-useful-snippets-ft-async-and-await-3h7b</guid>
      <description>&lt;p&gt;Quite a few people in my circle are either in development or looking to get into it as a career. The majority of them are learning JavaScript and the questions that I get asked most often relate to promises in some way.&lt;/p&gt;

&lt;p&gt;I thought it would be a good idea to write up a brief overview of promises, explaining what they are (on a high level) and go through some snippets that I find myself using in my day to day.&lt;/p&gt;

&lt;p&gt;While I did try to make this post as beginner friendly as possible, I assume that you, the reader, will have at least a basic understanding of JavaScript. If you don't, I highly recommend the &lt;a href="https://www.codecademy.com/learn/introduction-to-javascript" rel="noopener noreferrer"&gt;CodeCademy Introduction to JavaScript&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Exactly is a Promise?
&lt;/h2&gt;

&lt;p&gt;In simple terms, it's just a way for us to execute a bit of code and provide the result of that code &lt;em&gt;at some point in the future&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Imagine having a function that can execute in the background, while the rest of your application keeps happily chugging along, reacting to any button clicks, updating the DOM and etc. Once that function finishes executing (the Promise &lt;em&gt;resolves&lt;/em&gt;), we resume the execution path that requires the result of that function.&lt;/p&gt;

&lt;p&gt;The most common use case for promises is making API calls. You'd instruct your application to send a request to an API and do something with the result once your application receives a response. While that's happening in the background, or &lt;em&gt;asynchronously&lt;/em&gt;, you can still keep using the application.&lt;/p&gt;

&lt;p&gt;However, it's not just API calls that promises are useful for. In a broader sense, we use promises whenever we don't want to sit around waiting for IO - reading from or writing to disk, network requests or even intensive CPU tasks are some of the other use cases for promises.&lt;/p&gt;

&lt;p&gt;It might be a bit difficult to imagine still, but bare with. The examples should help conceptualize the idea of a promise a bit better.&lt;/p&gt;

&lt;p&gt;Here are the two main ways to use Promises - the standard API and the more novel &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// We return a promise object that can either resolve (success) or reject (failure)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;promised&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&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="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yay!&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// We call our promised() function and then follow it up with a .then()&lt;/span&gt;
&lt;span class="c1"&gt;// The function inside .then() will execute &lt;/span&gt;
&lt;span class="c1"&gt;// immediately after the promise resolves.&lt;/span&gt;
&lt;span class="c1"&gt;// The result of your promise will be passed in &lt;/span&gt;
&lt;span class="c1"&gt;// as a parameter of our callback function.&lt;/span&gt;
&lt;span class="nf"&gt;promised&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promiseResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promiseResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Should print out 'yay!'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Because we want to use await at the top level&lt;/span&gt;
&lt;span class="c1"&gt;// we have to wrap our code in a self-executing async function.&lt;/span&gt;
&lt;span class="c1"&gt;// This "hack" has a story of its own, I'll include it&lt;/span&gt;
&lt;span class="c1"&gt;// in Further Reading, but will not go over it here in much detail.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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;// async here just says that whatever this function returns &lt;/span&gt;
  &lt;span class="c1"&gt;// should be wrapped in a promise.&lt;/span&gt;
  &lt;span class="c1"&gt;// adding the sync keyword to our function also allows us to &lt;/span&gt;
  &lt;span class="c1"&gt;// use await within the context of that function.&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;promised&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yay!&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;promised&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

  &lt;span class="c1"&gt;// Should print out 'yay!'&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Disregarding the self-executing &lt;code&gt;async&lt;/code&gt; wrapper, the code using &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; looks much neater and, in most cases, is going to be preferred. However, we still need to know and understand the previous method since there are times when it's useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful Snippets
&lt;/h2&gt;

&lt;p&gt;In this section I'll cover some snippets that I use in my day to day that I think might be useful to others as well. They range from quite basic to more advanced. I highly recommend playing around with each snippet, to get more of an understanding of each of their intricacies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Promise Chaining
&lt;/h3&gt;

&lt;p&gt;This is a bit of a basic one, but possibly the most important. One of the great things about promises is that they can be chained together. Meaning, we can force sequential execution.&lt;/p&gt;

&lt;p&gt;Lets say we want to fetch a fake person from one API and then use another API to guess our fake persons age by their name - a completely logical thing to do. Here's what it'd look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchFakeUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// fetch() will return a promise.&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&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://randomuser.me/api/&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&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://api.agify.io/?name=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchFakeUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;fakeUserResponse&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;// Get the JSON data from the response. Returns a Promise.&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fakeUserResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// As soon as the Promise returned by json() resolves&lt;/span&gt;
&lt;span class="c1"&gt;// we'll continue executing the .then() chain.&lt;/span&gt;
&lt;span class="c1"&gt;// Note that the result returned by the previous .then()&lt;/span&gt;
&lt;span class="c1"&gt;// will be passed in as a parameter to our next .then() call&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;fakeUserData&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;// Return the name of our fake user down the Promise chain.&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fakeUserData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&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;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetchAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// We'll wait for the Promise returned by fetchAge to resolve,&lt;/span&gt;
&lt;span class="c1"&gt;// then continue executing the chain.&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;fetchAgeResponse&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;return&lt;/span&gt; &lt;span class="nx"&gt;fetchAgeResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;span class="nf"&gt;then&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Age: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&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;We can keep chaining the &lt;code&gt;.then()&lt;/code&gt; functions indefinitely, as long as we want to maintain that sequential control.&lt;/p&gt;

&lt;p&gt;One particular benefit of this is that it keeps our code relatively clean. Try and imagine doing something like this with nested callbacks, that'd be &lt;a href="http://callbackhell.com/" rel="noopener noreferrer"&gt;absolute hell&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;We can also convert the above to use the &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; notation. If we did, it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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;// The functions below don't need to be prefixed&lt;/span&gt;
  &lt;span class="c1"&gt;// with async, because fetch() already returns a Promise,&lt;/span&gt;
  &lt;span class="c1"&gt;// so we don't need to do any "wrapping" ourselves.&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchFakeUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// fetch() will return a promise.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&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://randomuser.me/api/&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&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://api.agify.io/?name=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// We'll use await to wait until the Promise &lt;/span&gt;
  &lt;span class="c1"&gt;// returned by our function resolves.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fakeUserResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchFakeUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// Will only resume execution after the above Promise resolves.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fakeUserData&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;fakeUserResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fakeUserData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;name&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;fetchAgeResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;fetchAgeData&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;fetchAgeResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Age: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&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;The above is more or less a direct translation of our implementation using &lt;code&gt;.then()&lt;/code&gt; chains. One thing to note though is that everything below an &lt;code&gt;await&lt;/code&gt; will be executed only &lt;em&gt;after&lt;/em&gt; that function completes. So if we're awaiting for an API request, anything that comes after will be executed only &lt;em&gt;after&lt;/em&gt; the request completes. This is particularly important to remember if you're using &lt;code&gt;await&lt;/code&gt; and want to execute multiple promises at the same time (or in &lt;em&gt;parallel&lt;/em&gt;). We'll get to this in another snippet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error Handling
&lt;/h3&gt;

&lt;p&gt;One thing we've not touched on just yet has been error handling. As with anything, we want to be able to catch any errors that our promises throw and gracefully handle them. With promises, there are a few different ways we can approach this.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using .then() and .catch()
&lt;/h4&gt;

&lt;p&gt;It's fairly straightforward when we're using &lt;code&gt;.then()&lt;/code&gt; - we'll use &lt;code&gt;.catch()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alwaysError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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;Oops!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success!&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;alwaysError&lt;/span&gt;
  &lt;span class="c1"&gt;// The function passed into .catch()&lt;/span&gt;
  &lt;span class="c1"&gt;// will receive the error as its parameter.&lt;/span&gt;
  &lt;span class="c1"&gt;// We can also return something from the .catch()&lt;/span&gt;
  &lt;span class="c1"&gt;// and continue our promise chain further.&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="nx"&gt;error&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;// console.log(error.message);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed!&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;userMessage&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;// If we would not have thrown an error,&lt;/span&gt;
    &lt;span class="c1"&gt;// our message would be 'Success'&lt;/span&gt;
    &lt;span class="c1"&gt;// as the catch() function is never triggered.&lt;/span&gt;
    &lt;span class="c1"&gt;// You can try this by commenting out&lt;/span&gt;
    &lt;span class="c1"&gt;// the "throw new Error" above.&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userMessage&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;If an error is thrown anywhere up the promise &lt;em&gt;chain&lt;/em&gt;, &lt;code&gt;.catch()&lt;/code&gt; will intercept it and it will immediately skip to executing the function that was passed into it. Once &lt;code&gt;.catch()&lt;/code&gt; finishes executing, the rest of the promise chain can continue with the value returned in the event of failure. Easy peasy, right?&lt;/p&gt;

&lt;h4&gt;
  
  
  Using try and catch
&lt;/h4&gt;

&lt;p&gt;Using &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; we'll want to use &lt;code&gt;try&lt;/code&gt; and &lt;code&gt;catch&lt;/code&gt; for our error handling. The only thing I'd like to draw your attention to here is that we have also extracted the error handling to a separate function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alwaysError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;// Comment the error out&lt;/span&gt;
    &lt;span class="c1"&gt;// to see the success flow.&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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;Oops!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success!&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;alwaysError&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Any error that is thrown by our promise&lt;/span&gt;
      &lt;span class="c1"&gt;// or if we manually call the reject method&lt;/span&gt;
      &lt;span class="c1"&gt;// will trigger this catch block.&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failure!&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="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Should print out "Failure!"&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing the above, we nicely encapsulate our logic of "getting a message" along with any error handling.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using await and .catch()
&lt;/h4&gt;

&lt;p&gt;Sometimes extracting your error handling into a separate function might feel like overkill. Maybe you just want to quickly catch, recover and continue execution without any extra overhead. Using the &lt;code&gt;try/catch&lt;/code&gt; approach we run into a few issues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alwaysError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;// Feel free to comment this error out&lt;/span&gt;
    &lt;span class="c1"&gt;// to see how it'd work without.&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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;Oops!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success!&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;try&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;alwaysError&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle our error here.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// But if we want to use anything&lt;/span&gt;
  &lt;span class="c1"&gt;// outside our try/catch block,&lt;/span&gt;
  &lt;span class="c1"&gt;// it will not be available.&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Message in this context will be "undefined"&lt;/span&gt;
  &lt;span class="c1"&gt;// and you will likely get an error.&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main problem with this example is that nothing is available outside our &lt;code&gt;try/catch&lt;/code&gt; block. There are ways to solve this, but none of them are elegant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Declare &lt;code&gt;message&lt;/code&gt; using &lt;code&gt;let message&lt;/code&gt; just before our &lt;code&gt;try/catch&lt;/code&gt; block, making it available outside the block scope. This, however, leaves us with a dangling, reassignable variable, so is not ideal.&lt;/li&gt;
&lt;li&gt;Just stick all our code in the &lt;code&gt;try/catch&lt;/code&gt; blocks. But this will &lt;a href="https://dev.to/jpswade/return-early-12o5"&gt;increase nesting&lt;/a&gt; and very likely also lead to code duplication.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A cool and quick way to handle the above problem that I have found is to use a mix of &lt;code&gt;await&lt;/code&gt; and &lt;code&gt;.catch()&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alwaysError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;// Comment the error out&lt;/span&gt;
    &lt;span class="c1"&gt;// to see the success flow.&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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;Oops!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success!&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;alwaysError&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="nx"&gt;error&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;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failure!&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Should print out "Failure!"&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above works because &lt;code&gt;.catch()&lt;/code&gt; and &lt;code&gt;alwaysError&lt;/code&gt; both return a Promise and in this scenario &lt;code&gt;await&lt;/code&gt; will wait for whichever Promise was returned last to resolve. This gives us a very elegant way to recover from an error that was thrown by our function and continue execution as if nothing happened.&lt;/p&gt;

&lt;p&gt;Personally, I really like this approach and would even prefer it to &lt;code&gt;try/catch&lt;/code&gt; in most cases, due to how clean and simple it is.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parallel Execution
&lt;/h3&gt;

&lt;p&gt;When talking about promise chaining using &lt;code&gt;await&lt;/code&gt;, we briefly touched on parallel execution. Going back to our example of getting a fake person from an API, lets pimp it out a bit. Lets try and guess the age, country and gender of the name that we get.&lt;/p&gt;

&lt;p&gt;A common solution to a problem like that would be something along the lines of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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;// We're prefixing the function with async&lt;/span&gt;
  &lt;span class="c1"&gt;// because we're going to be using await inside it.&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchFakeName&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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://randomuser.me/api/&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&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="nf"&gt;fetchAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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://api.agify.io/?name=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&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="nf"&gt;fetchCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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://api.nationalize.io/?name=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;country_id&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="nf"&gt;fetchGender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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://api.genderize.io/?name=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gender&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchFakeName&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;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;country&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;gender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchGender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gender&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;In this example, we'd wait until each API call was done. This happens because each &lt;code&gt;await&lt;/code&gt; will stop executing anything below it until the promise resolves. A good way around this is to use the &lt;code&gt;Promise.all()&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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;// We're prefixing the function with async&lt;/span&gt;
  &lt;span class="c1"&gt;// because we're going to be using await inside it.&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchFakeName&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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://randomuser.me/api/&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&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="nf"&gt;fetchAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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://api.agify.io/?name=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&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="nf"&gt;fetchCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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://api.nationalize.io/?name=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;country_id&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="nf"&gt;fetchGender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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://api.genderize.io/?name=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// We fetch a fake name first.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchFakeName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Promise.all() will execute all the promises&lt;/span&gt;
  &lt;span class="c1"&gt;// that we pass to it at the same time&lt;/span&gt;
  &lt;span class="c1"&gt;// and it will return a Promise,&lt;/span&gt;
  &lt;span class="c1"&gt;// resolving with all the values of our functions.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nf"&gt;fetchAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;fetchCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;fetchGender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gender&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;&lt;code&gt;Promise.all()&lt;/code&gt; will take our functions, all of which return promises, and it will await until all of them have resolved. One thing to note that's rather important is that if &lt;em&gt;one&lt;/em&gt; of the promises throws or rejects, &lt;code&gt;Promise.all()&lt;/code&gt; will immediately reject as well.&lt;/p&gt;

&lt;p&gt;Not really parallel, but as parallel as you can get &lt;a href="https://youtu.be/8aGhZQkoFbQ" rel="noopener noreferrer"&gt;on a single thread.&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Racing
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Promise.race()&lt;/code&gt; is a bit of a weird one. It's very similar to &lt;code&gt;Promise.all()&lt;/code&gt; where it takes an array of promises in and it returns a single promise back. But unlike &lt;code&gt;Promise.all()&lt;/code&gt; it will not wait until all the promises you give it will resolve. Instead, &lt;code&gt;Promise.race()&lt;/code&gt; will resolve or reject as soon as soon as the first promise given rejects or resolves.&lt;/p&gt;

&lt;p&gt;The two primary use cases for it that I've found are for &lt;em&gt;loading indicators&lt;/em&gt; and &lt;em&gt;performance checks&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In terms of a performance check, you can fire off requests to multiple endpoints, and you'll resolve with the response from the one that completes first. Fairly straightforward.&lt;/p&gt;

&lt;p&gt;Loading indicators is where it gets slightly more interesting. Lets say you're making an API call that you know can take up anywhere from 10ms to 5s and in case of it taking too long, you want to provide the visitor some visual feedback so that they don't navigate away. Here's a basic example of what that would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchFakeName&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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://randomuser.me/api/&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Wait 5 seconds before returning the response of our API call.&lt;/span&gt;
    &lt;span class="c1"&gt;// This will help us simulate a slow network.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resolve&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="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;5000&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;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showLoading&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Wait 0.5 seconds before letting the user know&lt;/span&gt;
    &lt;span class="c1"&gt;// the request is taking longer than usual.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is taking a while. Please wait!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;500&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;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;race&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nf"&gt;fetchFakeName&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Name: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="nf"&gt;showLoading&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="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="c1"&gt;// Should print out&lt;/span&gt;
  &lt;span class="c1"&gt;// This is taking a while. Please wait!&lt;/span&gt;
  &lt;span class="c1"&gt;// Name: [name]&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One thing to keep in mind is that the other promises &lt;em&gt;will not cancel&lt;/em&gt; and will still complete in the background.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sequential Execution
&lt;/h3&gt;

&lt;p&gt;While promises are great for executing various tasks asynchronously, sometimes we want to make sure that we are executing certain actions in a sequence. Due to the nature of promises, this can prove quite difficult, but combining promises with &lt;code&gt;Array.reduce()&lt;/code&gt; we can solve this issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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;// The number of processors &lt;/span&gt;
  &lt;span class="c1"&gt;// that we have in our pipeline&lt;/span&gt;
  &lt;span class="c1"&gt;// can be completely dynamic,&lt;/span&gt;
  &lt;span class="c1"&gt;// as long as they accept a string and return a string.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// Convert to uppercase&lt;/span&gt;
    &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="c1"&gt;// Prefix with Name&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="c1"&gt;// We are utilising Array.reduce here&lt;/span&gt;
  &lt;span class="c1"&gt;// and reduce our array of promises to a single promise.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// Our reduce callback is going to take the result&lt;/span&gt;
    &lt;span class="c1"&gt;// of the previous (or initial) promise, &lt;/span&gt;
    &lt;span class="c1"&gt;// wait for it to be processed and&lt;/span&gt;
    &lt;span class="c1"&gt;// pass its result into the next promise.&lt;/span&gt;
    &lt;span class="c1"&gt;// processName will return the very last promise from the array.&lt;/span&gt;
    &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;processed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;processor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;processor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;processed&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialName&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;processedName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;processName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Should print out Name: ED&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;processedName&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;I have personally found this extremely useful when trying to build data processing pipelines in JavaScript. Or in other words - in cases where you have a piece of data (a JSON object, for example) and you want to pass that JSON object through a series of asynchronous processors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Notes
&lt;/h2&gt;

&lt;p&gt;I hope people find this compilation useful. I highly recommend you read some of the material linked in Further Reading &amp;amp; References, especially if you are new and find promises hard to grasp still.&lt;/p&gt;

&lt;p&gt;If you have any questions or would like to discuss or provide feedback - feel free to shout at me on Twitter &lt;a href="https://twitter.com/SkepticalHippoh" rel="noopener noreferrer"&gt;@SkepticalHippoh&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading &amp;amp; References:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fetch API: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Promise: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Promise.all(): &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Promise.race(): &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Array.reduce(): &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Return Early: &lt;a href="https://dev.to/jpswade/return-early-12o5"&gt;https://dev.to/jpswade/return-early-12o5&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Callback Hell: &lt;a href="http://callbackhell.com/" rel="noopener noreferrer"&gt;http://callbackhell.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How can I use async await at the top level: &lt;a href="https://stackoverflow.com/questions/46515764/how-can-i-use-async-await-at-the-top-level" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/46515764/how-can-i-use-async-await-at-the-top-level&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;"What the heck is the event loop anyway?" by Philip Roberts: &lt;a href="https://www.youtube.com/watch?v=8aGhZQkoFbQ" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=8aGhZQkoFbQ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Mozilla layoffs 🦊, COVID19 tech industry 🦠 and a bit on side projects 👷‍♀️ - Synk #4</title>
      <dc:creator>Ed</dc:creator>
      <pubDate>Sun, 16 Aug 2020 10:54:29 +0000</pubDate>
      <link>https://forem.com/skepticalhippoh/mozilla-layoffs-covid19-tech-industry-and-a-bit-on-side-projects-synk-4-2cfb</link>
      <guid>https://forem.com/skepticalhippoh/mozilla-layoffs-covid19-tech-industry-and-a-bit-on-side-projects-synk-4-2cfb</guid>
      <description>&lt;p&gt;It's been a very interesting couple of weeks in the world of development. From a restructuring of Mozilla to noteworthy career tips, we've got you covered! &lt;/p&gt;

&lt;p&gt;Remember, if you enjoy the content, you can subscribe over at &lt;a href="https://synk.sh" rel="noopener noreferrer"&gt;synk.sh&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  📰 The News
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.theverge.com/2020/8/11/21363424/mozilla-layoffs-quarter-staff-250-people-new-revenue-focus" rel="noopener noreferrer"&gt;Mozilla restructure leads to 250 employees being laid off&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;As part of a company restructure, apparently triggered by the current coronavirus situation, Mozilla has decided to reshift focus only to specific products, leading them to lay off various dev favourites including the MDN team (whose birthday we just celebrated in the last issue) and the DevTools team. A truly sad day for those affected by the restructuring, as well as those who heavily rely on Firefox for development.&lt;/p&gt;

&lt;p&gt;💬DISCUSS: &lt;a href="https://www.reddit.com/r/webdev/comments/i8dwht/mozilla_have_laid_off_the_entire_mdn_writers_team/" rel="noopener noreferrer"&gt;REDDIT &lt;/a&gt;| &lt;a href="https://news.ycombinator.com/item?id=24132494" rel="noopener noreferrer"&gt;HACKERNEWS &lt;/a&gt;| &lt;a href="https://twitter.com/SteveALee/status/1293487542382333952" rel="noopener noreferrer"&gt;TWITTER&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.hiringlab.org/2020/07/30/tech-sector-covid19-impact/" rel="noopener noreferrer"&gt;Here is how the tech sector is dealing with the impact of COVID-19&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The impact of coronavirus has been felt by many across the tech industry, and the data seems to confirm that. Though there is some issue with this data, such as the fact that it mostly focuses on the US and does not offer a breakdown of various seniority levels, it's fair to say that many industries, including tech, will be struggling for a while.&lt;/p&gt;

&lt;p&gt;💬DISCUSS: &lt;a href="https://www.reddit.com/r/programming/comments/i0td3m/indeedcom_data_show_that_the_job_market_for_tech/" rel="noopener noreferrer"&gt;REDDIT&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.theregister.com/2020/08/06/intel_nda_source_code_leak/" rel="noopener noreferrer"&gt;20GB of NDA Intel blueprints have been leaked&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you've been waiting for Intel documentation for years, then you're finally in luck, as 20GB of Intel blueprints have now been leaked! In all seriousness though, this leak may could bring on a new wave of Intel exploits we've seen in the past few years (Spectre and Meltdown). Also noteworthy is that the leaker's account has already been suspended from Twitter.&lt;/p&gt;

&lt;p&gt;💬DISCUSS: &lt;a href="https://www.reddit.com/r/programming/comments/i4xxnk/20gb_leak_of_intel_data_whole_git_repositories/" rel="noopener noreferrer"&gt;REDDIT &lt;/a&gt;| &lt;a href="https://news.ycombinator.com/item?id=24074588" rel="noopener noreferrer"&gt;HACKERNEWS&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🔭 Code Discovery
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/renovatebot/renovate" rel="noopener noreferrer"&gt;A tool to automatically update your dependencies and keep things secure&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Renovate is a very nifty, highly customizable tool that can automate pull requests whenever your dependencies need updating. Think of it like a supercharged version of Github's own dependabot.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/simdjson/simdjson#bindings-and-ports-of-simdjson" rel="noopener noreferrer"&gt;A different, faster way of parsing JSON&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;JSON is everywhere, and parsing it isn't always as fast as one might wish. Simdjson aims to change that, and it's already used by companies such as Microsoft, Shopify, and Yandex for that exact reason. Check out the Bindings and Ports of the README to find out how you can use it in your own application.&lt;/p&gt;

&lt;h1&gt;
  
  
  🎓 Career Development
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/viraptor/reverse-interview" rel="noopener noreferrer"&gt;Always ask questions in your interviews!&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Many people fixate so much on answering questions during interviews that they tend to forget they are a two-way street. Both parties have to find each other appealing, so here are some questions you may wish to ask; a reverse interview!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.reddit.com/r/cscareerquestions/comments/i8aynq/i_no_longer_thing_cs_is_the_right_career_for_me/" rel="noopener noreferrer"&gt;CS is not for everyone, and that is absolutely fine&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Working in CS can be absolutely exhausting, as tiresome as any other job. Whether you're burning yourself out or just not enjoying the job at all, it's okay to think about changing a career. After all, your wellbeing is more important than the job you're doing.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://zeroequalsfalse.com/posts/it-is-ok-to-only-code-at-work/" rel="noopener noreferrer"&gt;Only coding at work is okay&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Anecdotally, a lot of us have probably experienced the pressure of feeling like we constantly have to be coding. But the truth is, it's absolutely fine to only code at work. Will you be the top programmer at your company? Perhaps not, but are the sacrifices you have to make to get there worth it? That's for you to decide, and no one else.&lt;/p&gt;

&lt;p&gt;💬DISCUSS: &lt;a href="https://www.reddit.com/r/programming/comments/i7t6qv/it_is_perfectly_ok_to_only_code_at_work_you_can/" rel="noopener noreferrer"&gt;REDDIT&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🤔 Miscellaneous
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://adamwathan.me/tailwindcss-from-side-project-byproduct-to-multi-mullion-dollar-business/" rel="noopener noreferrer"&gt;How Adam Wathan turned Tailwind CSS into a multi-million dollar business&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Adam Wathan, the creator of the fantastic Tailwind CSS framework, has shared some insight into his journey of turning Tailwind from a side project to a succesful business. If there is one key takeaway here, it's this: keep building things. Just because one product you made wasn't succesful doesn't mean the next one (or the 100th!) will not be either.&lt;/p&gt;

&lt;p&gt;💬DISCUSS: &lt;a href="https://www.reddit.com/r/webdev/comments/i3erm0/tailwind_css_from_sideproject_byproduct_to/" rel="noopener noreferrer"&gt;REDDIT &lt;/a&gt;| &lt;a href="https://news.ycombinator.com/item?id=24031290" rel="noopener noreferrer"&gt;HACKERNEWS &lt;/a&gt;| &lt;a href="https://twitter.com/adamwathan/status/1290267369936269314" rel="noopener noreferrer"&gt;TWITTER&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/nodejs/nodejs.dev" rel="noopener noreferrer"&gt;NodeJS best practice, from the source&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Want to see what a proper NodeJS project looks like? Then check out the official repository and spend some time perusing its wonders. Maybe you'll notice some cool things, such as the fact that 64.9% of the code is written in TypeScript. A sign of things to come?&lt;/p&gt;

</description>
      <category>newsletter</category>
      <category>showdev</category>
      <category>webdev</category>
      <category>news</category>
    </item>
    <item>
      <title>Arctic Code Vault, GitHub ReadMes and Svelte - Synk #3</title>
      <dc:creator>Ed</dc:creator>
      <pubDate>Sat, 01 Aug 2020 20:50:55 +0000</pubDate>
      <link>https://forem.com/skepticalhippoh/arctic-code-vault-github-readmes-and-svelte-synk-3-3d8b</link>
      <guid>https://forem.com/skepticalhippoh/arctic-code-vault-github-readmes-and-svelte-synk-3-3d8b</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;📰 The News&lt;/strong&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://github.blog/2020-07-16-github-archive-program-the-journey-of-the-worlds-open-source-code-to-the-arctic/" rel="noopener noreferrer"&gt;Your code may have been stored in an arctic vault!&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;The year is 3020. Humanity is on the brink of extinction. The elders have decided to look into the past for answers. The mysterious GitHub Artic Code Vault is finally opened. The first film is unraveled in great anticipation, and the first message arrives: &lt;em&gt;“Hello World!”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💬 DISCUSS: &lt;a href="https://www.reddit.com/r/programming/comments/hstcpi/github_achives_all_of_the_repositories_present_on/" rel="noopener noreferrer"&gt;REDDIT&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://svelte.dev/blog/svelte-and-typescript" rel="noopener noreferrer"&gt;Svelte now supports TypeScript&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Svelte, an up-and-coming front-end framework contender, has just announced support for TypeScript. While Svelte hasn’t seen as much adoption as Vue or React, this is definitely a step forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💬 DISCUSS: &lt;a href="https://www.reddit.com/r/webdev/comments/hvcd7p/svelte_now_supports_typescript/" rel="noopener noreferrer"&gt;REDDIT&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://hacks.mozilla.org/2020/07/mdn-web-docs-15-years-young/" rel="noopener noreferrer"&gt;Happy 15th birthday to MDN Web Docs!&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A fantastic resource for all web developers, MDN Web Docs has just celebrated its 15th birthday. Celebrate by reading something you haven’t seen before!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💬 DISCUSS: &lt;a href="https://www.reddit.com/r/webdev/comments/hwt2gl/mdn_web_docs_15_years_young/" rel="noopener noreferrer"&gt;REDDIT&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;🔭 Code Discovery&lt;/strong&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://www.reddit.com/r/webdev/comments/hxjw6e/showoff_saturday_i_created_a_cli_tool_to_draw_an/" rel="noopener noreferrer"&gt;Draw images on your GitHub contribution graph&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Reddit user &lt;a href="https://www.reddit.com/user/me-at-work/" rel="noopener noreferrer"&gt;/u/me-at-work&lt;/a&gt; has created &lt;a href="https://github.com/blaise-io/contribution" rel="noopener noreferrer"&gt;a very nifty tool&lt;/a&gt; that uses custom git commit dates to draw images on your GitHub contribution graph. Check it out and tweet us your creations!&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://github.com/anuraghazra/github-readme-stats" rel="noopener noreferrer"&gt;Spice up your readmes with auto-generated stats&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Thinking up good information to include in your readme can be quite daunting. With this tool, you can include some relevant, fun, and informative stats with little effort.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://github.com/gto76/python-cheatsheet" rel="noopener noreferrer"&gt;Cannot remember how to do X with Python? Look here&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;I absolutely love a good cheatsheet and often use various ones (hello Markdown, my old friend). If you often find yourself in a similar situation with Python, here’s a goood bookmark to have.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;🎓 Career Development&lt;/strong&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://ronjeffries.com/articles/018-01ff/abandon-1/" rel="noopener noreferrer"&gt;Is Agile good for everything? A discussion&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Love it or hate it, the Agile methodology is extremely common in dev workspaces. Prompted by an article by Ron Jeffries, one of the original co-signatories of the Agile Manifesto, read up on a good discussion about the pros and cons of Agile, as well as what it means for developers vs managers (good and bad).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💬 DISCUSS: &lt;a href="https://www.reddit.com/r/programming/comments/hygojk/i_hate_agile_development_because_its_been_coopted/" rel="noopener noreferrer"&gt;REDDIT&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://www.reddit.com/r/webdev/comments/hrsrn1/kinda_new_to_programming_somehow_got_hired_code/" rel="noopener noreferrer"&gt;Your code passing QA has nothing to do with being a good developer&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Whether you’ve been in the industry for 6 months or 6 years, your code will likely fail QA. Does that make you a bad developer? Certainly not! Join this discussion and see how many developers struggle with the same things.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;🤔 Miscellaneous&lt;/strong&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://docs.microsoft.com/en-gb/learn/paths/build-javascript-applications-nodejs/?WT.mc_id=mslearn-reddit-abartolo" rel="noopener noreferrer"&gt;Microsoft releases NodeJS tutorials&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;There are not a ton of great resources on the web to learn NodeJS so it’s great to see a selection of curated, well-made tutorials by none other than Microsoft.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💬 DISCUSS: &lt;a href="https://www.reddit.com/r/webdev/comments/hwdcyy/microsoft_launches_build_javascript_applications/" rel="noopener noreferrer"&gt;REDDIT&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;a href="https://ui.dev/webpack/" rel="noopener noreferrer"&gt;Struggling with Webpack? Read this&lt;/a&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Webpack is a lot of things, but easy to understand is not one of them. This “gentle introduction” aims to change that a little bit and is definitely worth a read, even if you’ve just wondered what it’s all about. In case you’re looking for something that is perhaps easier to understand and simpler to start with, check out &lt;a href="https://parceljs.org/" rel="noopener noreferrer"&gt;Parcel&lt;/a&gt; and &lt;a href="https://rollupjs.org/guide/en/" rel="noopener noreferrer"&gt;Rollup&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💬 DISCUSS: &lt;a href="https://www.reddit.com/r/javascript/comments/hwka8k/webpack_a_gentle_introduction/" rel="noopener noreferrer"&gt;REDDIT&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Enjoy the content?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://synk.sh/" rel="noopener noreferrer"&gt;Subscribe to Synk.&lt;/a&gt; Web development news, cool code and career advice delivered to your inbox, every two weeks.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>newsletter</category>
      <category>news</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Synk #2 - 🏦 Barclays, 🐘 PHP and ⛓ Safe Links.</title>
      <dc:creator>Ed</dc:creator>
      <pubDate>Sat, 25 Jul 2020 14:09:21 +0000</pubDate>
      <link>https://forem.com/skepticalhippoh/synk-2-barclays-php-and-safe-links-4be9</link>
      <guid>https://forem.com/skepticalhippoh/synk-2-barclays-php-and-safe-links-4be9</guid>
      <description>&lt;p&gt;Hey! 👋 I posted a while back about &lt;a href="https://dev.to/skepticalhippoh/launched-synk-a-newsletter-for-web-developers-9gl"&gt;launching a newsletter for developers&lt;/a&gt;. I'm over the moon to finally be able to share our newsletter with everyone in the &lt;strong&gt;DEV&lt;/strong&gt; community. This is our second issue, which we feel is a major improvement over our very first one. Let us know what you think!&lt;/p&gt;

&lt;p&gt;If you enjoy the content and want more of it, make sure to subscribe over at &lt;a href="https://synk.sh" rel="noopener noreferrer"&gt;Synk&lt;/a&gt; for a biweekly delivery straight to your inbox!&lt;/p&gt;

&lt;h1&gt;
  
  
  📰 The News
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.theregister.com/2020/07/03/barclays_bank_javascript_wayback_machine/" rel="noopener noreferrer"&gt;🏦 Barclays used Wayback Machine as CDN&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;An inquisitive &lt;a href="https://twitter.com/immunda/status/1278783894683336704" rel="noopener noreferrer"&gt;Twitter user (@immunda)&lt;/a&gt; found that Barclays had been using the Internet Archive's Wayback Machine as a CDN for some of its JS assets. Not sure how that one got through QA!&lt;/p&gt;

&lt;p&gt;💬 Discuss: &lt;a href="https://www.reddit.com/r/webdev/comments/hkhvsm/barclays_bank_serve_their_js_assets_through_a_3rd/" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://laravel-news.com/microsoft-dropping-php-support" rel="noopener noreferrer"&gt;Microsoft will drop official support of PHP on Windows&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Though it's likely that someone in the community will pick it up, Microsoft will no longer officially support PHP on Windows. Will this affect you?&lt;/p&gt;

&lt;p&gt;💬 Discuss: &lt;a href="https://twitter.com/Ocramius/status/1281315727593611264/" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🔭 Code Discovery
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/gothinkster/realworld" rel="noopener noreferrer"&gt;Check out a real-world app in different languages!&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;When you want to learn a new language, you'll often follow a tutorial that'll lead to the creation of a to-do app, or something similar. But what abou real world apps? In this GitHub project, you'll be able to see a "Medium.com clone" and what it looks like in all kinds of different languages. Neat!&lt;/p&gt;

&lt;p&gt;💬Discuss: &lt;a href="https://twitter.com/synk_sh/status/1283500900636663810" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/florinpop17/app-ideas" rel="noopener noreferrer"&gt;Get inspired with these app ideas&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Learning is already hard, and trying to think of ways to apply your learning can often be even harder. Instead of doing everything yourself, why don't you check out these ideas for apps to inspire you? Who knows, you may even make something successful with one of them!&lt;/p&gt;

&lt;p&gt;💬 Discuss: &lt;a href="https://twitter.com/synk_sh/status/1283501183747989509" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🎓 Career Development
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.reddit.com/r/cscareerquestions/comments/hqmug1/remote_internship_accidentally_called_my_manager/" rel="noopener noreferrer"&gt;A tale of two dads(or what to do when saying something silly in the workplace)&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Whether you've called your manager dad like this Reddit user, or accidentally sent a message on Slack asking everyone to give you a sex (sec), the most important thing to remember is everyone makes mistakes!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.reddit.com/r/programming/comments/hr0frb/youve_only_added_two_lines_why_did_that_take_two/" rel="noopener noreferrer"&gt;"Why did this take so long, you only added two lines of code!"&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Regardless of what we may think, a lot of people outside the industry seem to think that the more lines of code you write, the more you are actually contributing to the product/project/company/happiness-of-manager. Here are some things you can say when someone asks why those 2 lines of code took an equal number of days to write.&lt;/p&gt;

&lt;h1&gt;
  
  
  🤔 Miscellaneous
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://twitter.com/dan_spratling/status/1277543614663536645" rel="noopener noreferrer"&gt;Some portfolio advice by a veteran&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Twitter user and industry veteran Dan Spratling recently took it upon himself to shell out some advice regarding dev portfolios. Read on and you might find something useful for your own site.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://kentcdodds.com/blog/how-i-structure-express-apps/" rel="noopener noreferrer"&gt;How to structure Express apps&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Kent C. Dodds, JS teacher and Twitter afficionado, shows us how he structures his own Express apps. This is a very useful guide for both those of us just starting our Express journey, and those who may wish to check out a different opinion.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://twitter.com/frontenddude/status/1277862161663119360?s=20" rel="noopener noreferrer"&gt;Careful when using the target="_blank" attribute&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Something that happens very often in web development is that we tend to forget how important the basics are, especially when it comes to security. In this case, let's remember how important it is to use the target="_blank" attribute safely.&lt;/p&gt;

&lt;p&gt;💬 Discuss: &lt;a href="https://www.reddit.com/r/webdev/comments/hiimnd/using_the_target_blank_attribute_can_expose_your/" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Want to help us improve? Give us a shout &lt;a href="https://twitter.com/synk_sh" rel="noopener noreferrer"&gt;@synk_sh&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>news</category>
      <category>career</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Launched Synk - A newsletter for web developers!</title>
      <dc:creator>Ed</dc:creator>
      <pubDate>Sun, 28 Jun 2020 16:02:16 +0000</pubDate>
      <link>https://forem.com/skepticalhippoh/launched-synk-a-newsletter-for-web-developers-9gl</link>
      <guid>https://forem.com/skepticalhippoh/launched-synk-a-newsletter-for-web-developers-9gl</guid>
      <description>&lt;p&gt;Hey everyone! We're two web devs (junior and lead) who have been working on this for the past few months and we're really excited to finally show it all off!&lt;/p&gt;

&lt;p&gt;We started Synk because we want to give back to the community and also learn ourselves. Here's where we're hoping Synk can provide value to web developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take the anxiety out of trying to keep up to date with the latest news in our ever-evolving industry.&lt;/li&gt;
&lt;li&gt;Expose developers to a wider range of technologies that would allow them to become more well rounded and at the very least hold a conversation with someone using different tech.&lt;/li&gt;
&lt;li&gt;Help junior developers broaden their horizons and sound smarter during interviews 🤓&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our first issue is due to come out in a few weeks time and we'd be really happy to hear any feedback from anyone and everyone 🙏&lt;/p&gt;

&lt;p&gt;If you have any questions, be it Synk or generic web dev, do not hesitate to reach out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://synk.sh" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz11wth58uqh03dryrnp0.png" alt="Synk Up!" width="300" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are also on &lt;a href="https://www.producthunt.com/posts/synk-sh-stay-in-synk" rel="noopener noreferrer"&gt;ProductHunt&lt;/a&gt; and &lt;a href="https://www.indiehackers.com/product/synk" rel="noopener noreferrer"&gt;IndieHackers&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
