ol><li><i>Set the send() flag.</i></li><li>If the synchronous flag is unset, then:
…
Handle the tasks queue on the networking tasks source.
If ~50ms have passed since these steps were last invoked, terminate these steps.</li></ol><p id="8fde">We should keep our eyes on <b>tasks queue</b> and <b>50ms</b>. Doesn’t this sound like something we’ve looked into together? Yes. It’s a <i>setTimeout</i>! So we know that <i>XMLHttpRequest</i> actually uses <i>setTimeout</i> to be executed. If <i>XMLHttpRequest</i> uses <i>setTimeout</i>, then it should be blocked by infinite <i>Promises</i>, since they are microtasks.</p>
<figure id="cecb">
<div>
<div>
<iframe class="gist-iframe" src="/gist/moonformeli/ecfc1459da85527f0a0e4fcf8a7601be.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="a1be">I ran this example in Codepen; the total time to log <code>this.responseText</code> was around 114,000ms. It means that even though <i>XMLHttpRequest</i> is an asynchronous function, there is still a way to block its execution, so you should place your code in the right place.</p><h1 id="0041">fetch</h1><p id="2413"><i>fetch</i> is a newer API that has extra features that <i>XMLHttpRequest</i> doesn’t have. It returns a <i>Promise</i> that resolves to the Response to that request, whether it’s successful or not.</p><p id="1181">With <i>fetch</i>:</p><ul><li>Cache API is available with the request and the response object.</li><li><i>fetch</i> won’t receive cross-site cookies.</li><li><i>fetch</i> won’t send cookies.</li><li>A <i>promise</i> from fetch won’t reject on an HTTP error status.</li></ul><p id="fa0f">Only <i>XMLHttpRequest</i> can:</p><ul><li>Abort a request.</li><li>Report progress.</li></ul><p id="b362">Another difference is that fetch isn’t supportive in IE, since it uses <i>Promise</i>, which IE doesn’t support either. So if you should support the older browsers, you should use <i>XMLHttpRequest</i>.</p><p id="aea0">MDN said there’s an interface that allows you to abort a request, but it says it’s an experimental technology. It doesn’t support IE and does support Safari partially. Check it out from <a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController">here</a>.</p><p id="c11b"><i>fetch</i> gives you some more convenient methods to check the status of your response.</p><p id="daee"><code>res.json()</code> parses the response as the JSON object. If you use <i>Promise,</i> you should return <code>res.json()</code> again to get the right JSON object in the next <code>.then</code> chain. If you use <code>async</code> and <code>await</code>, you can simply add <code>await</code>.</p><div id="76d6"><pre><span class="hljs-comment">// Promise</span>
fetch(url)
.then(<span class="hljs-function"><span class="hljs-params">res</span> =></span> {
<span class="hljs-keyword">return</span> res.json();
})
.then(<span class="hljs-function"><span class="hljs-params">data</span> =></span> {
<span class="hljs-built_in">console</span>.<span class="hljs-built_in">log</span>(data);
});</pre></div><div id="80d0"><pre><span class="hljs-comment">// async & await</span>
<span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-built_in">url</span>);
<span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> res.json();
<span class="hljs-built_in">console</span>.log(data);</pre></div><p id="269a">Inside <i>fetch</i>, you can see how it is described.</p><p id="71de">To queue a fetch task on a <i>request</i> to run an operation, run these steps:</p><ol><li>If the request’s client is null, terminate these steps.</li><li>Queue a task to run an operation on the request’s client’s responsible event loop, using the networking task source.</li></ol><p id="fe9b">What we should see is “Queue a task”. In this context, “queue a task” means to add a task to the task queue. Since <i>fetch</i> returns a <i>Promise</i>, it’s a microtask. But you can get the result in <
Options
code>then</code>. What if there are many microtasks running?</p>
<figure id="5a7d">
<div>
<div>
<iframe class="gist-iframe" src="/gist/moonformeli/b2b530baebcff4f66c6809921cf8e461.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="680d">Like we experimented with in <i>XMLHttpRequest</i>, <i>fetch</i> also was blocked for many milliseconds until the previous microtasks were completely done executing.</p><h1 id="5ab7">Axios</h1><p id="e5f0"><i>Axios</i> is a modern HTTP request library for both the browser and Node. It has over 67K stars from users. It has taken the best things from <i>XMLHttpRequest</i> and <i>fetch</i>.</p><p id="438b">So, the way to use <i>Axios</i> is actually simple and easy. It’s very similar to how to use <i>fetch</i>. You pass a URL to Axios as the first argument, but instead, you should use the right HTTP method, such as <i>Axios.get</i>.</p><div id="e00f"><pre><span class="hljs-comment">// Promise </span>
axios.get(<span class="hljs-string">'/user?ID=12345'</span>)
.then(<span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) {
<span class="hljs-comment">// handle success</span>
<span class="hljs-built_in">console</span>.<span class="hljs-built_in">log</span>(response);
})
.catch(<span class="hljs-keyword">function</span> (<span class="hljs-params">error</span>) {
<span class="hljs-comment">// handle error</span>
<span class="hljs-built_in">console</span>.<span class="hljs-built_in">log</span>(error);
})
.finally(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) {
<span class="hljs-comment">// always executed</span>
});</pre></div><div id="1dcd"><pre><span class="hljs-comment">// async & await</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">getUser</span>(<span class="hljs-params"></span>) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">'/user?ID=12345'</span>);
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(response);
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(error);
}
}</pre></div><h1 id="a1ad">Conclusion</h1><p id="813f">A JavaScript event is a very complex and difficult topic, but you should know it well if you use JavaScript every day. I did my best to explain what I know about JavaScript events. I hope that I could be at least a little bit of help with your understanding of this!</p><h1 id="f9fd">More in this series</h1><ul><li><a href="https://readmedium.com/be-the-master-of-the-event-loop-in-javascript-part-2-54637d49889f">Read Be the Master of the Event Loop in JavaScript (Part 2)</a></li><li><a href="https://readmedium.com/be-the-master-of-the-event-loop-in-javascript-part-3-df51ab655c94">Read Be the Master of the Event Loop in JavaScript (Part 3)</a></li></ul><h1 id="788c">Resources</h1><ul><li><a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest — MDN</a></li><li><a href="https://xhr.spec.whatwg.org/#interface-xmlhttprequest">XMLHttpRequest Interface — WhatWG</a></li><li><a href="https://jsonplaceholder.typicode.com/">Rest API example site — JsonPlaceHolder</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch — MDN</a></li><li><a href="https://stackoverflow.com/questions/35549547/fetch-api-vs-xmlhttprequest">fetch API vs XMLHttpRequest — StackOverflow</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController">AbortController — MDN</a></li><li><a href="https://javascript.info/fetch">fetch — JavaScript.info</a></li><li><a href="https://github.com/axios/axios">Axios — Github</a></li></ul></article></body>
Be the Master of the Event Loop in JavaScript (Part 3)
In this post, I will talk about asynchronous functions in JavaScript.
XMLHttpRequest
fetch
Axios
XMLHttpRequest
JavaScript allows you to fetch data in an asynchronous way. The oldest, most classic way is to use XMLHttpRequest. It’s a constructor function that allows you to send an HTTP request to the server.
const oReq = new XMLHttpReqeust();
Now oReq has the XMLHttpRequest object. To make an HTTP request, you should open the request first.
The XHR method is not case-sensitive. So, you could even write it like “geT”, since it’ll be uppercased during the process. You can then send the request to the server.
oReq.send();
To receive the response from your request, you should attach a callback function to the XMLHttpRequest object.
oReq.addEventListener('load', function () {
console.log(this.responeText);
});
// Result{"userId":1,"id":1,"title":"delectus aut autem","completed":false}
Note that you ought to use a normal function rather than an arrow function, since a normal function’s this is bound to the XMLHttpRequest, while an arrow function is bound to window. responseText of XMLHttpRequest doesn’t exist in the prototype chain of e.
'responseText'in e === false
But, don’t you think it’s strange? I have explained in the previous posts that there are a few types of tasks in JavaScript. But why is it called an asynchronous function?
If the synchronous flag is unset, then:
…
- Handle the tasks queue on the networking tasks source.
- If ~50ms have passed since these steps were last invoked, terminate these steps.
We should keep our eyes on tasks queue and 50ms. Doesn’t this sound like something we’ve looked into together? Yes. It’s a setTimeout! So we know that XMLHttpRequest actually uses setTimeout to be executed. If XMLHttpRequest uses setTimeout, then it should be blocked by infinite Promises, since they are microtasks.
I ran this example in Codepen; the total time to log this.responseText was around 114,000ms. It means that even though XMLHttpRequest is an asynchronous function, there is still a way to block its execution, so you should place your code in the right place.
fetch
fetch is a newer API that has extra features that XMLHttpRequest doesn’t have. It returns a Promise that resolves to the Response to that request, whether it’s successful or not.
With fetch:
Cache API is available with the request and the response object.
fetch won’t receive cross-site cookies.
fetch won’t send cookies.
A promise from fetch won’t reject on an HTTP error status.
Only XMLHttpRequest can:
Abort a request.
Report progress.
Another difference is that fetch isn’t supportive in IE, since it uses Promise, which IE doesn’t support either. So if you should support the older browsers, you should use XMLHttpRequest.
MDN said there’s an interface that allows you to abort a request, but it says it’s an experimental technology. It doesn’t support IE and does support Safari partially. Check it out from here.
fetch gives you some more convenient methods to check the status of your response.
res.json() parses the response as the JSON object. If you use Promise, you should return res.json() again to get the right JSON object in the next .then chain. If you use async and await, you can simply add await.
// async & awaitconst res = await fetch(url);
const data = await res.json();
console.log(data);
Inside fetch, you can see how it is described.
To queue a fetch task on a request to run an operation, run these steps:
If the request’s client is null, terminate these steps.
Queue a task to run an operation on the request’s client’s responsible event loop, using the networking task source.
What we should see is “Queue a task”. In this context, “queue a task” means to add a task to the task queue. Since fetch returns a Promise, it’s a microtask. But you can get the result in then. What if there are many microtasks running?
Like we experimented with in XMLHttpRequest, fetch also was blocked for many milliseconds until the previous microtasks were completely done executing.
Axios
Axios is a modern HTTP request library for both the browser and Node. It has over 67K stars from users. It has taken the best things from XMLHttpRequest and fetch.
So, the way to use Axios is actually simple and easy. It’s very similar to how to use fetch. You pass a URL to Axios as the first argument, but instead, you should use the right HTTP method, such as Axios.get.
A JavaScript event is a very complex and difficult topic, but you should know it well if you use JavaScript every day. I did my best to explain what I know about JavaScript events. I hope that I could be at least a little bit of help with your understanding of this!