Previously in JavaScript Essentials: Part 4, We discussed if and else statements, for and while loops. In this part, we will look at:
Comments are great and we are now going to talk about it. It is so late that you should know what a comment is. Anyway, a comment in our program is not executed. A comment is meant to document our code. There are three ways to add comments in Javascript. We have the inline, multiline and JsDoc.
In-line
// this is a number const numberOfBirds = 3; // the above comment is useless since the initial value assigned to the variable // is physically a number and the variable name also has a number in it // so use comments wisely by using proper naming
Multiline
/* Everything in here is or will be ignored. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. */ const emptyString = "";
JsDoc
/** * This is a multiline comment * * But used for documentation */
Comments can be placed anywhere; however, be careful when placing them after (or at the end) a line of code or below or above it.
In javascript, semi-colon, ;, is not required however, it helps sometimes. There are tools that help you with it. A semi-colon indicates the end of a statement. Good.
Indentations are used to arrange code for clarity and ease of reading. The tab key (on the keyboard) is used in indenting. Indentations are sometimes "tabs" or "spaces". The space is usually 2 or 4. If you are using vscode, you don't have to worry.
There were some exercises from JavaScript Essentials: Part 4 which included but were not limited to "fizzbuzz", password and email validation, etc. If you were to have followed my pseudocode, you'd run into some issues. I will provide a snippet that considers the order.
fizzbuzz for a single number
const givenNumber = 3; if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); }
fizzbuzz for an array
const numbers = [3, 6, 10, 15]; for (const givenNumber of numbers) { if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); } }
password validation
const veryWeakPassword = "PrQ1V_"; // const veryWeakPassword = "rtfy67Fg"; // const veryWeakPassword = "OlJgRc__1qwPVa"; console.log(`Password validation for "${veryWeakPassword}"`); // - be six characters if (veryWeakPassword.length !== 6) { console.log( `- Password must have 6 characters => "${veryWeakPassword}" has '${veryWeakPassword.length}' characters` ); } // - start with uppercase p, 'P' else if (!veryWeakPassword.startsWith("P")) { console.log( `- Password must start with 'P' => it is ${veryWeakPassword.startsWith( "P" )} that "${veryWeakPassword}" starts with 'P'` ); } // - end with underscore else if (!veryWeakPassword.endsWith("_")) { console.log( `- Password must end with '_' => it is ${veryWeakPassword.endsWith( "_" )} that "${veryWeakPassword}" ends with '_'` ); } // - have uppercase q, 'Q' else if (!veryWeakPassword.includes("Q")) { console.log( `- Password must have uppercase q, 'Q' => it is ${veryWeakPassword.includes( "Q" )} that "${veryWeakPassword}" has 'Q'` ); } // - have lowercase r, 'r' else if (!veryWeakPassword.includes("r")) { console.log( `- Password must have lowercase r, 'r' => it is ${veryWeakPassword.includes( "r" )} that "${veryWeakPassword}" has 'r'` ); } // - have its fifth character as uppercase v, 'V' // fifth character with have index = fifth position - 1 = 4 // const fifthCharacter = veryWeakPassword[4] else if (veryWeakPassword.charAt(4) !== "V") { console.log( `- Password must have its fifth character as uppercase v, 'V' => "${veryWeakPassword}" has its 5th character as '${veryWeakPassword.charAt( 4 )}'` ); } else { console.log(`${veryWeakPassword} is a valid password`); }
Some other solutions would be using nested if and else.
// password validation const veryWeakPassword = "PrQ1V_"; // const veryWeakPassword = "rtfy67Fg"; // const veryWeakPassword = "OlJgRc__1qwPVa"; console.log(`Password validation for "${veryWeakPassword}"`); // - be six characters if (veryWeakPassword.length === 6) { if (veryWeakPassword.startsWith("P")) { if (veryWeakPassword.endsWith("_")) { if (veryWeakPassword.includes("Q")) { if (veryWeakPassword.includes("r")) { if (veryWeakPassword.charAt(4) === "V") { console.log(`${veryWeakPassword} is a valid password`); } else { console.log( `- Password must have its fifth character as uppercase v, 'V' => "${veryWeakPassword}" has its 5th character as '${veryWeakPassword.charAt( 4 )}'` ); } } else { console.log( `- Password must have lowercase r, 'r' => it is ${veryWeakPassword.includes( "r" )} that "${veryWeakPassword}" has 'r'` ); } } else { console.log( `- Password must have uppercase q, 'Q' => it is ${veryWeakPassword.includes( "Q" )} that "${veryWeakPassword}" has 'Q'` ); } } else { console.log( `- Password must end with '_' => it is ${veryWeakPassword.endsWith( "_" )} that "${veryWeakPassword}" ends with '_'` ); } } else { console.log( `- Password must start with 'P' => it is ${veryWeakPassword.startsWith( "P" )} that "${veryWeakPassword}" starts with 'P'` ); } } else { console.log( `- Password must have 6 characters => "${veryWeakPassword}" has '${veryWeakPassword.length}' characters` ); }
What do you think about the two snippets? Practically the second snippet, even though it works, is not that great.
A function is a piece of code that can be reused. Usually, a function does a specific thing. One thing. It can be anything.
Let's look at the general form (structure) of a function in JavaScript.
// this is a number const numberOfBirds = 3; // the above comment is useless since the initial value assigned to the variable // is physically a number and the variable name also has a number in it // so use comments wisely by using proper naming
We can have a function that prints "hello world"
/* Everything in here is or will be ignored. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. */ const emptyString = "";
We did ourselves the favour to name our function with a name that describes what the function does.
Now, when we have a function, we have to "call" it for it to be executed. To call a function, you need the function's name followed by ( and ). If the function takes a parameter, you'd pass the argument in the ( and ). In our case, for the "hello world" function, we have to do, printHelloWorld();.
/** * This is a multiline comment * * But used for documentation */
Let's move in a little direction that will broaden our arsenal and make creating functions fun. Consider this function that adds two numbers and then prints a text telling you what happened.
const givenNumber = 3; if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); }
Is this giving you ideas? We can write our "fizzbuzz" and validations using functions. We can be so stingy and delicate that we'd write each validation requirement as a function. It happens. Just don't overdo it.
Now, consider the add function. What if we want to add different numbers, what do we do? We can create another function that. We can also alter the values directly. Right? Yeah. You will be amazed by what we can accomplish with functions.
First of all, if we want to add different numbers we can change the numbers.
const numbers = [3, 6, 10, 15]; for (const givenNumber of numbers) { if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); } }
Okay, let's alter the function to add 6 and 100 rather. Now we have to alter the function. There is a solution to this and it is to introduce parameters (data via variables). Then we'd pass those data as arguments.
Let's analyze our add function. The add function operates on x and y and operands. We can pass different values to x and y by passing x and y as parameters.
const veryWeakPassword = "PrQ1V_"; // const veryWeakPassword = "rtfy67Fg"; // const veryWeakPassword = "OlJgRc__1qwPVa"; console.log(`Password validation for "${veryWeakPassword}"`); // - be six characters if (veryWeakPassword.length !== 6) { console.log( `- Password must have 6 characters => "${veryWeakPassword}" has '${veryWeakPassword.length}' characters` ); } // - start with uppercase p, 'P' else if (!veryWeakPassword.startsWith("P")) { console.log( `- Password must start with 'P' => it is ${veryWeakPassword.startsWith( "P" )} that "${veryWeakPassword}" starts with 'P'` ); } // - end with underscore else if (!veryWeakPassword.endsWith("_")) { console.log( `- Password must end with '_' => it is ${veryWeakPassword.endsWith( "_" )} that "${veryWeakPassword}" ends with '_'` ); } // - have uppercase q, 'Q' else if (!veryWeakPassword.includes("Q")) { console.log( `- Password must have uppercase q, 'Q' => it is ${veryWeakPassword.includes( "Q" )} that "${veryWeakPassword}" has 'Q'` ); } // - have lowercase r, 'r' else if (!veryWeakPassword.includes("r")) { console.log( `- Password must have lowercase r, 'r' => it is ${veryWeakPassword.includes( "r" )} that "${veryWeakPassword}" has 'r'` ); } // - have its fifth character as uppercase v, 'V' // fifth character with have index = fifth position - 1 = 4 // const fifthCharacter = veryWeakPassword[4] else if (veryWeakPassword.charAt(4) !== "V") { console.log( `- Password must have its fifth character as uppercase v, 'V' => "${veryWeakPassword}" has its 5th character as '${veryWeakPassword.charAt( 4 )}'` ); } else { console.log(`${veryWeakPassword} is a valid password`); }
Instead of having the values of x and y as internal values in add, we pass them. Now the difference between parameters and arguments is that parameters are passed when creating (defining) the function. Arguments are the values passed when calling the function. So in function add(x, y), x and y are parameters (we can say placeholders, representing the data to be passed to the function). In add(3, 30);, 3 and 30 are passed as arguments (the actual values to be processed). Note that the order of the argument and parameters must match else we'd be in serious debt.
Do you think it is enough to take on the big guns? Well, I think you can. You just have to be calm and know what you are doing. I will provide some snippets.
// this is a number const numberOfBirds = 3; // the above comment is useless since the initial value assigned to the variable // is physically a number and the variable name also has a number in it // so use comments wisely by using proper naming
Do the same for the "fizzbuzz". Wrap a function around the snippet. You don't have to comment on the variables used. Look at what data needs to be passed to the function (input).
We can pass as many parameters to a function. However, I'd encourage you to set some limits. There are some professionals who say about three is enough. Some say about fewer than five. You have to be smart about it. For now, let's say that whenever the number of parameters exceeds three, we would use an array or an object. Yeah. We can pass an array or an object as an argument.
/* Everything in here is or will be ignored. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. */ const emptyString = "";
Write a function that calculates the average of an array of numbers by completing this function.
/** * This is a multiline comment * * But used for documentation */
At this point, it should be clear that functions can take arguments. Practically, our functions will return a value or something value after a computation is done. The computed value is returned from the function. A function that returns a value is of the form:
const givenNumber = 3; if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); }
Remember the add function? Instead of logging the value inside the function, we will return it and assign that value to a variable then reuse the value later.
const numbers = [3, 6, 10, 15]; for (const givenNumber of numbers) { if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); } }
This is as simple as we can put it. Do the same for the calculateInterest function.
A function can return anything returnable.
An arrow function is another way to write a function. Usually, I use arrow functions when I have a simple function that does a very minute "thing" or in array or string methods for looping. You can use it in place of the function declarations (named functions). We say, function, to indicate we want to create a function. Arrow functions have the same features as the declarative function.
Arrow functions are called so because of =>, the fat arrow operator. It is of the form, perhaps you've seen before:
const veryWeakPassword = "PrQ1V_"; // const veryWeakPassword = "rtfy67Fg"; // const veryWeakPassword = "OlJgRc__1qwPVa"; console.log(`Password validation for "${veryWeakPassword}"`); // - be six characters if (veryWeakPassword.length !== 6) { console.log( `- Password must have 6 characters => "${veryWeakPassword}" has '${veryWeakPassword.length}' characters` ); } // - start with uppercase p, 'P' else if (!veryWeakPassword.startsWith("P")) { console.log( `- Password must start with 'P' => it is ${veryWeakPassword.startsWith( "P" )} that "${veryWeakPassword}" starts with 'P'` ); } // - end with underscore else if (!veryWeakPassword.endsWith("_")) { console.log( `- Password must end with '_' => it is ${veryWeakPassword.endsWith( "_" )} that "${veryWeakPassword}" ends with '_'` ); } // - have uppercase q, 'Q' else if (!veryWeakPassword.includes("Q")) { console.log( `- Password must have uppercase q, 'Q' => it is ${veryWeakPassword.includes( "Q" )} that "${veryWeakPassword}" has 'Q'` ); } // - have lowercase r, 'r' else if (!veryWeakPassword.includes("r")) { console.log( `- Password must have lowercase r, 'r' => it is ${veryWeakPassword.includes( "r" )} that "${veryWeakPassword}" has 'r'` ); } // - have its fifth character as uppercase v, 'V' // fifth character with have index = fifth position - 1 = 4 // const fifthCharacter = veryWeakPassword[4] else if (veryWeakPassword.charAt(4) !== "V") { console.log( `- Password must have its fifth character as uppercase v, 'V' => "${veryWeakPassword}" has its 5th character as '${veryWeakPassword.charAt( 4 )}'` ); } else { console.log(`${veryWeakPassword} is a valid password`); }
or
// password validation const veryWeakPassword = "PrQ1V_"; // const veryWeakPassword = "rtfy67Fg"; // const veryWeakPassword = "OlJgRc__1qwPVa"; console.log(`Password validation for "${veryWeakPassword}"`); // - be six characters if (veryWeakPassword.length === 6) { if (veryWeakPassword.startsWith("P")) { if (veryWeakPassword.endsWith("_")) { if (veryWeakPassword.includes("Q")) { if (veryWeakPassword.includes("r")) { if (veryWeakPassword.charAt(4) === "V") { console.log(`${veryWeakPassword} is a valid password`); } else { console.log( `- Password must have its fifth character as uppercase v, 'V' => "${veryWeakPassword}" has its 5th character as '${veryWeakPassword.charAt( 4 )}'` ); } } else { console.log( `- Password must have lowercase r, 'r' => it is ${veryWeakPassword.includes( "r" )} that "${veryWeakPassword}" has 'r'` ); } } else { console.log( `- Password must have uppercase q, 'Q' => it is ${veryWeakPassword.includes( "Q" )} that "${veryWeakPassword}" has 'Q'` ); } } else { console.log( `- Password must end with '_' => it is ${veryWeakPassword.endsWith( "_" )} that "${veryWeakPassword}" ends with '_'` ); } } else { console.log( `- Password must start with 'P' => it is ${veryWeakPassword.startsWith( "P" )} that "${veryWeakPassword}" starts with 'P'` ); } } else { console.log( `- Password must have 6 characters => "${veryWeakPassword}" has '${veryWeakPassword.length}' characters` ); }
Let's rewrite the add function using the arrow function.
function functionName(/* parameters */) { // do something }
=>, indicates a return of the value from the x y express. So the return keyword is used implicitly. Again we can explicitly return a value from the function using the return keyword however, we have to add the functions block.
// this is a number const numberOfBirds = 3; // the above comment is useless since the initial value assigned to the variable // is physically a number and the variable name also has a number in it // so use comments wisely by using proper naming
The difference between the two is that in the second, we added a block, { and } and a return keyword that returns a value from the function. Again, you can choose to return a value or not.
We can pass functions as arguments to other functions. Essentially, we treat functions as values. Let's consider this trivial example.
/* Everything in here is or will be ignored. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. */ const emptyString = "";
Another place we can do this is with array methods or string methods. Consider this function
/** * This is a multiline comment * * But used for documentation */
We can see that we can pull out the callback function, (total, element) => total element, 0. In fact, it is the total element we can replace.
const givenNumber = 3; if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); }
You know we pass another function that takes 2 numbers argument and returns a number. We don't even have to create a function.
We have done some maths before but this time we will use functions to abstract the operators.
const numbers = [3, 6, 10, 15]; for (const givenNumber of numbers) { if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); } }
The last parameter is called a default parameter and usually, it is placed as
the last argument. This is something that you have to do if you are going to
use default values. This snippet is not that different from the previous
one except for the introduction of the default parameter which means for the third
argument, we can choose to pass a value for it or not.
const veryWeakPassword = "PrQ1V_"; // const veryWeakPassword = "rtfy67Fg"; // const veryWeakPassword = "OlJgRc__1qwPVa"; console.log(`Password validation for "${veryWeakPassword}"`); // - be six characters if (veryWeakPassword.length !== 6) { console.log( `- Password must have 6 characters => "${veryWeakPassword}" has '${veryWeakPassword.length}' characters` ); } // - start with uppercase p, 'P' else if (!veryWeakPassword.startsWith("P")) { console.log( `- Password must start with 'P' => it is ${veryWeakPassword.startsWith( "P" )} that "${veryWeakPassword}" starts with 'P'` ); } // - end with underscore else if (!veryWeakPassword.endsWith("_")) { console.log( `- Password must end with '_' => it is ${veryWeakPassword.endsWith( "_" )} that "${veryWeakPassword}" ends with '_'` ); } // - have uppercase q, 'Q' else if (!veryWeakPassword.includes("Q")) { console.log( `- Password must have uppercase q, 'Q' => it is ${veryWeakPassword.includes( "Q" )} that "${veryWeakPassword}" has 'Q'` ); } // - have lowercase r, 'r' else if (!veryWeakPassword.includes("r")) { console.log( `- Password must have lowercase r, 'r' => it is ${veryWeakPassword.includes( "r" )} that "${veryWeakPassword}" has 'r'` ); } // - have its fifth character as uppercase v, 'V' // fifth character with have index = fifth position - 1 = 4 // const fifthCharacter = veryWeakPassword[4] else if (veryWeakPassword.charAt(4) !== "V") { console.log( `- Password must have its fifth character as uppercase v, 'V' => "${veryWeakPassword}" has its 5th character as '${veryWeakPassword.charAt( 4 )}'` ); } else { console.log(`${veryWeakPassword} is a valid password`); }
In const total = performActionOnArray(numArray, add); we could have passed a function directly
// password validation const veryWeakPassword = "PrQ1V_"; // const veryWeakPassword = "rtfy67Fg"; // const veryWeakPassword = "OlJgRc__1qwPVa"; console.log(`Password validation for "${veryWeakPassword}"`); // - be six characters if (veryWeakPassword.length === 6) { if (veryWeakPassword.startsWith("P")) { if (veryWeakPassword.endsWith("_")) { if (veryWeakPassword.includes("Q")) { if (veryWeakPassword.includes("r")) { if (veryWeakPassword.charAt(4) === "V") { console.log(`${veryWeakPassword} is a valid password`); } else { console.log( `- Password must have its fifth character as uppercase v, 'V' => "${veryWeakPassword}" has its 5th character as '${veryWeakPassword.charAt( 4 )}'` ); } } else { console.log( `- Password must have lowercase r, 'r' => it is ${veryWeakPassword.includes( "r" )} that "${veryWeakPassword}" has 'r'` ); } } else { console.log( `- Password must have uppercase q, 'Q' => it is ${veryWeakPassword.includes( "Q" )} that "${veryWeakPassword}" has 'Q'` ); } } else { console.log( `- Password must end with '_' => it is ${veryWeakPassword.endsWith( "_" )} that "${veryWeakPassword}" ends with '_'` ); } } else { console.log( `- Password must start with 'P' => it is ${veryWeakPassword.startsWith( "P" )} that "${veryWeakPassword}" starts with 'P'` ); } } else { console.log( `- Password must have 6 characters => "${veryWeakPassword}" has '${veryWeakPassword.length}' characters` ); }
Before anything, let's define some terms. Promises are important in our niche.
Synchronous operation: These are operations that are executed sequentially, from top to bottom, one after the other. For some operations A1 and A2, A1 has to be completed before A2 will be executed. This way, A2 will not be executed until A1. At a time one operation is executed. This drawback is called blocking.
function functionName(/* parameters */) { // do something }
The output for the above is in a linear order as written above.
// function to print "hello world" function printHelloWorld() { console.log("Hello world"); }
In short, the code we have written so far is all executed in a synchronous order and we can tell when one line will be executed.
Asynchronous operations: These are operations that are not executed sequentially. These operations run concurrently. These could be several operations running at the same time, practically, bit by bit. Since the success or execution of one operation is independent of the order and doesn't impede the execution of other lines, we call this behaviour non-blocking. We can not tell when an asynchronous line will be executed.
printHelloWorld(); // the output of this function will be on the console/terminal
And this is the output.
function add() { const x = 3; const y = 20; const sum = x + y; console.log(`${x} + ${y} = ${sum}`); } add(); // 3 + 20 = 23
Can you identify the async operation based on the output?
It is the setTimeout function. Let's say it runs in the background. It is non-blocking, so the last console.log was executed.
Some Async Operations
A Promise provides a means for managing or handling asynchronous operations. It is a way of knowing the state an async operation is in, when it is executed, and whether it is "fulfilled" or it failed.
Let's create a Promise
A promise has the form:
// this is a number const numberOfBirds = 3; // the above comment is useless since the initial value assigned to the variable // is physically a number and the variable name also has a number in it // so use comments wisely by using proper naming
new and Promise are keywords. resolve and reject are callback functions. We can replace them with other names. By conversion, we use resolve and reject.
Handle a promise
Promise has then method which provides the resolved value, catch method which provides the rejected error and there is the finally which is a way to clean up after the whole process. finally is optional though. Here is a simple example you can play with.
/* Everything in here is or will be ignored. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. */ const emptyString = "";
Look at the output and see how the code is executed. console.log("Bye"); was not the last to be executed. We created our async operation using a promise and handled it using then and catch. If we are thinking of executing these operations in order, then we can or have to put the remaining logic inside the then block.
/** * This is a multiline comment * * But used for documentation */
What happened?
The issue with this approach to handling promises is that we tend to nest or chain this operation, the then block fattens and it is not that friendly. So let's look at async and await.
In the normal flow of data, we don't want the async operation to run in the background. We want to listen to it and use its result to do something else (as we did in the then and catch).
Let's create an async operation and handle it using async and await.
We know how to create named functions and arrow functions.
const givenNumber = 3; if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); }
To make a function asynchronous, we use the async keyword.
const numbers = [3, 6, 10, 15]; for (const givenNumber of numbers) { if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); } }
Now whatever operation goes into the block of the function and let's say in the async function we want to create, we would have to deal with another async operation, then we can use the await.
const veryWeakPassword = "PrQ1V_"; // const veryWeakPassword = "rtfy67Fg"; // const veryWeakPassword = "OlJgRc__1qwPVa"; console.log(`Password validation for "${veryWeakPassword}"`); // - be six characters if (veryWeakPassword.length !== 6) { console.log( `- Password must have 6 characters => "${veryWeakPassword}" has '${veryWeakPassword.length}' characters` ); } // - start with uppercase p, 'P' else if (!veryWeakPassword.startsWith("P")) { console.log( `- Password must start with 'P' => it is ${veryWeakPassword.startsWith( "P" )} that "${veryWeakPassword}" starts with 'P'` ); } // - end with underscore else if (!veryWeakPassword.endsWith("_")) { console.log( `- Password must end with '_' => it is ${veryWeakPassword.endsWith( "_" )} that "${veryWeakPassword}" ends with '_'` ); } // - have uppercase q, 'Q' else if (!veryWeakPassword.includes("Q")) { console.log( `- Password must have uppercase q, 'Q' => it is ${veryWeakPassword.includes( "Q" )} that "${veryWeakPassword}" has 'Q'` ); } // - have lowercase r, 'r' else if (!veryWeakPassword.includes("r")) { console.log( `- Password must have lowercase r, 'r' => it is ${veryWeakPassword.includes( "r" )} that "${veryWeakPassword}" has 'r'` ); } // - have its fifth character as uppercase v, 'V' // fifth character with have index = fifth position - 1 = 4 // const fifthCharacter = veryWeakPassword[4] else if (veryWeakPassword.charAt(4) !== "V") { console.log( `- Password must have its fifth character as uppercase v, 'V' => "${veryWeakPassword}" has its 5th character as '${veryWeakPassword.charAt( 4 )}'` ); } else { console.log(`${veryWeakPassword} is a valid password`); }
The await tells javascript to "wait" and receive the resolved or fulfilled value from the promise.
// password validation const veryWeakPassword = "PrQ1V_"; // const veryWeakPassword = "rtfy67Fg"; // const veryWeakPassword = "OlJgRc__1qwPVa"; console.log(`Password validation for "${veryWeakPassword}"`); // - be six characters if (veryWeakPassword.length === 6) { if (veryWeakPassword.startsWith("P")) { if (veryWeakPassword.endsWith("_")) { if (veryWeakPassword.includes("Q")) { if (veryWeakPassword.includes("r")) { if (veryWeakPassword.charAt(4) === "V") { console.log(`${veryWeakPassword} is a valid password`); } else { console.log( `- Password must have its fifth character as uppercase v, 'V' => "${veryWeakPassword}" has its 5th character as '${veryWeakPassword.charAt( 4 )}'` ); } } else { console.log( `- Password must have lowercase r, 'r' => it is ${veryWeakPassword.includes( "r" )} that "${veryWeakPassword}" has 'r'` ); } } else { console.log( `- Password must have uppercase q, 'Q' => it is ${veryWeakPassword.includes( "Q" )} that "${veryWeakPassword}" has 'Q'` ); } } else { console.log( `- Password must end with '_' => it is ${veryWeakPassword.endsWith( "_" )} that "${veryWeakPassword}" ends with '_'` ); } } else { console.log( `- Password must start with 'P' => it is ${veryWeakPassword.startsWith( "P" )} that "${veryWeakPassword}" starts with 'P'` ); } } else { console.log( `- Password must have 6 characters => "${veryWeakPassword}" has '${veryWeakPassword.length}' characters` ); }
When we execute the above snippet we get an error similar to, Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension..
We can fix this issue easily. Run the command, npm init -y. Go into the package.json file and add the line, "type": "module". The package.json should look like
// this is a number const numberOfBirds = 3; // the above comment is useless since the initial value assigned to the variable // is physically a number and the variable name also has a number in it // so use comments wisely by using proper naming
Now, rerun the snippet and you should get an output similar to
/* Everything in here is or will be ignored. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. */ const emptyString = "";
Now, let's say we want to handle the promise rejection error, in case there is no, we have to use the try and catch clause around the async call.
/** * This is a multiline comment * * But used for documentation */
There won't be any promise rejection because we set, const result = true. Set it to false. And our output should be similar to
const givenNumber = 3; if (givenNumber % 3 === 0 && givenNumber % 5 === 0) { console.log("fizzbuzz"); } else if (givenNumber % 3 === 0) { console.log("fizz"); } else if (givenNumber % 5 === 0) { console.log("buzz"); }
So the purpose of talking about promises and async and await is to let you know that we will be doing that a lot. Refer to the examples of asynchronous operations listed above.
async and await, try and catch and finally are keywords.
At this point where we have discussed functions and promises and how to handle them, I think we are about 50% equipped with the "knowledge" to manipulate data (flow). What is left is to become used to writing javascript code and be a competent javascript programmer. Get your hands dirty with JavaScript. That's the only way you will code a backend API and not feel restrained because you have the idea but don't know what to do.
Next is to write some code and solve some problems then actually start building APIs. That is what we will be doing next, however, I will encourage you to check out the resources below.
These are materials that will be helpful in understanding Promises, async and await and event loop.
These are some exercises you'd like to try your hands on.
The above is the detailed content of JavaScript Essentials: Part 5. For more information, please follow other related articles on the PHP Chinese website!