You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
10 KiB

3 months ago
import { addBanner, addArticle, addTitle, addHeader, addParagraph, addClassParagraph, addSubHeader, addSmallHeader, addOrderedList, addUnorderedList, addBlockquote, addInset, addInsetList, addInsetCodeListing, addInsetBulletList, addImageWithCaption, addButtonGroup, addSidebar, addSyntax, menu, global_menu } from '/scripts/import.js';
import { local_menu } from '/scripts/webdev.js';
const heading = document.querySelector(".heading");
const global = document.querySelector(".global_menu");
const local = document.querySelector(".local_menu");
const sidebar = document.querySelector(".sidebar");
const main = document.querySelector(".main_content");
heading.append(addTitle("Learning the JavaScript Language"));
heading.append(addParagraph("Joe Chellman - LinkedIn Learning - May 2023"));
heading.append(addParagraph("A Few More Advanced Pieces"));
main.append(addHeader("Asynchronous Code: Waiting is the Hardest Part"))
main.append(addParagraph("We saw several examples of callback functions in the previous chapter and in some instances, the callback function was called straight away and that is called synchronous processing. That's really just a fancy way of saying that all of the commands are executed in sequence although that doesn't necessarily mean that this is the same sequence as shown in the code."));
main.append(addParagraph("For example, various programming constructs can change the sequence in which commands so let's say that you have a file with 100 lines of code, when you run it the browser (that is, the JavaScript interpreter) will start at line 1 and when that's executed it will go on to line 2 and if there are no commands that change this sequence, it will continue on until all 100 lines of code have been executed."));
main.append(addParagraph("In programming terms, this is a construct called sequence, but there are a couple of other constructs which can alter the flow of the instructions and these are selection (conditional statements which can cause some statements to be skipped depending on the result of evaluating some condition) or iteration (loops which can cause some statements to be repeated a number of times)."));
main.append(addParagraph("Strictly speaking, functions will also disrupt this flow but this is just a case of the process of programming being simplified by allowing some functionality to be abstracted away into a function so this would fall under sequence even though it disrupts the flow of statements in a strictly linear sense. For example, if your code contains a function in lines 190 to 200 and that function is called on line 10, the effect is the same as if all that code was placed on line 10."));
main.append(addParagraph("Some programming languages also allowed a goto statement that allowed you to switch execution to another part of the code but you will only ever see this in old code and as far as I'm aware, it is not available in JavaScript."));
main.append(addParagraph("They key point is that regardless of which order the statements are processed in, they are processed synchronously in that one statement is processed after another but each statement must wait before the previous one has completed before it can be executed."));
main.append(addParagraph("In broader terms, you might think of this as your code being single-tasked. That is, only one task is executed at a time and in some sequence. I would imagine that any modern computer today will provide multitasking capabilities with multiple CPUs/cores and modern languages provide facilities to allow the programmer to take advantage of that. As we will see in the next section, JavaScript is no exception."));
main.append(addHeader("Promises, async and await"));
main.append(addParagraph("Consider this snippet of code."));
main.append(addInsetCodeListing(["jQuery.get(\"https://httpbin.org/get?data=1\", function(response) {", " // Now I have some data", "});"]));
main.append(addParagraph("The first thing to note is that this is using the jQuery library which is not really covered in this course but this is just an introduction to several methods of asynchronous code so that you will get to see it and hopefully will at least recognise it if you see it out in the wild."));
main.append(addParagraph("This is using the jQuery get method which takes two parameters, the first being a url and the second being a callback function that will execute once a response is received. The response is passed to the callback function so essentially this is a case of sending a request and call a function with it when the request has been received."));
main.append(addParagraph("This is very straightforward but it does have a couple of drawbacks, the first of which is that you may not be using jQuery! The second and possibly more severe drawback is something you will only see if you need to send several such calls that depend on the previous call being completed as shown below."));
main.append(addImageWithCaption("./images/nested_callbacks.png", "Nested callback functions."));
main.append(addParagraph("Although the syntax here is simple enough, you can nest calls to as many levels as you like but the results can be quite difficult to read (this is sometimes called callback hell)! You can find more information on the jQuery get method in the official <a href=' https://api.jquery.com/get/'>jQuery Docs</a>."));
main.append(addParagraph("Note that the endpoint here is <a href=' https://httpbin.org/'>httpbin</a> which is, in its own words, a simple HTTP Request and Response Service. In our examples, it is just being used to test the jQuery get method."));
main.append(addParagraph("It may be worth pointing out that this section isn't really intended to teach you advanced techniques in JavaScript. It's more of a teaser of other advanced topics you might want to learn more about so there will be very little in the way of explanations but lots of links to help you discover more."));
main.append(addParagraph("The next thing we want to look at is promises and these can be used as follows:"));
main.append(addInsetCodeListing(["// One Promise", "axios.get(\"https://httpbin.org/get\").then(function(response) {", " // now I have some data","});"]));
main.append(addParagraph("Here, we are using the Axios library (you can find documentation for it <a href=' https://axios-http.com/docs/intro'>here</a> and similarly to htttpbin, axios will allow us to send get requests to an api but rather than just returning a response, it also returns a promise. One of the neat things about promises in JavaScript is that they have a method called then which allows us to perform some processing on the response."));
main.append(addParagraph("You might have noticed as well that the then method is being tagged on the end of the axios call which essentially means we are passing the then method to that call. To be more precise, we are passing it to the result of making that call, ie, the promise."));
main.append(addParagraph("The request can be in any of three states."));
main.append(addSmallHeader("pending"));
main.append(addParagraph("This is the initial state and shows that the request has yet to be completed, successfully or otherwise!"));
main.append(addSmallHeader("fulfilled"));
main.append(addParagraph("The operation completed successfully."));
main.append(addSmallHeader("rejected"));
main.append(addParagraph("The operation completed unsuccessfully."));
main.append(addParagraph("If you want to make a number of calls in sequence, you don't have to nest them, you can put these at the same level in your code one after the other."));
main.append(addParagraph("At the moment, this is probably the most common form of code written to make network requests but async and await are relatively new and make working with promises a little bit neater so you may start to see these appearing more often."));
main.append(addParagraph("These are demonstrated in the code shown below."));
main.append(addInsetCodeListing(["// One request", "async function getOneThing() {", " var response = await axios.get(\"https://httpbin.org/get\");", "", " // now I have some data", "}"]));
main.append(addParagraph("Notice that this is an async function so it is expected to work asynchronously and it's using the await keyword almost as if it were a datatype. Essentially it is saying here is a get request but we will wait for the API to return a response and will then assign that response to the variable response."));
main.append(addParagraph("This isn't too different to the way we used promises in the previous example but Is much more concise and it is easier to chain a sequence of these requests together as shown below."));
main.append(addInsetCodeListing(["// Multiple requests", "async function getLotsOfThings() {", " var response1 = await axios.get(\"https://httpbin.org/get\");", " var response2 = await axios.get(\"https://httpbin.org/get\");", " var response3 = await axios.get(\"https://httpbin.org/get\");", "", " // now I have lots of data", "}"]));
main.append(addHeader("Object-Oriented JavaScript: Prototypes and Classes"));
main.append(addParagraph("We have already seen various objects but we haven't seen classes and that will probably seem weird to anyone who has used objects in any other language, but JavaScript is a more or less conventional object-oriented language."));
main.append(addParagraph("One of the fundamental aspects of object-oriented programming languages that makes them so useful is inheritance and JavaScript uses a model known as Prototypal Inheritance in which every object has a link to its parent and this goes all the way back (or up, if you prefer) to the object that all other objects inherit from and as in most object-oriented languages, that is Object."));
main.append(addParagraph("One of the quirks with objects in JavaScript (or at least something that will look like a quirk if you are more familiar with objects in Java or C++) is that you can create an object simply by setting the value of some variable to something that looks like an object."));
main.append(addParagraph("For example, we saw this in chapter 3 where we created a bird object with the command"));
main.append(addInsetCodeListing(["let bird = {", " genus: \"corvus\",", " species: \"corvax\",", " commonName: \"raven\",", " callType: \"squawky\",", " quote: \"Nevermore\",", " maxOffspring: 5,", " noisy: true,", " deadly: false,", "};"]));
addSidebar("webdev");