字幕列表 影片播放 列印英文字幕 SELA KASEPA: So hello, and welcome to this S50 seminar, which is JavaScript, The Basics. So quick introduction. I am Sela, junior studying computer science. And we'll be going through the basics of JavaScript. So in this case, we are going to go over the different data types that we have, some functions, some looping constructs. And then we'll also go through JavaScript asynchronous data. So look at callbacks, promises, async await. So yeah. So we can dive into the seminar. OK, so we'll start with basic introductory JavaScript, which is, what is JavaScript and what can you do with it? So JavaScript, in a nutshell, is a programming language. And then some of the terms that you hear, whenever people are talking about JavaScript, is it's single-threaded. It's asynchronous. So I won't dive into these terms right now, but we'll come back to them. So a brief history of JavaScript is JavaScript was originally built to run in the browser. And so browsers come in [? beta ?] JavaScript engines. And then JavaScript engines, in this case, are responsible for executing JavaScript code. So some examples are SpiderMonkey and Firefox, and then V8, a V8 engine in Chrome. But then sometime later on, some brilliant engineer came along and then decided to invade Chrome's V8 engine into some C++ program. And then he called this firmware Node, Node.js. And so what this Node.js framework enables us to do is it enables us to execute JavaScript code outside the browser. And so with us getting this capability to execute JavaScript code outside the browser, that meant we could now write server side JavaScript. We could build entire web applications solely in JavaScript because it can now write our backend in JavaScript and simply run our JavaScript in the Node.js framework. OK, so that's kind of a brief history in JavaScript. And so now we're going to dive into working with JavaScript in the browser. So I'm going to open a browser terminal. So I'm going to open a browser window. And then in this browser, I want us to go over working with JavaScript in the browser. So like I mentioned, Chrome has a V8 engine, which is responsible for executing JavaScript code. So if you open up Chrome, because I'm using the Chrome browser, so I'll show you how I got here. So you can literally open up the Inspect. OK, so you can literally open up the Inspect option. And so this brings us a bunch of options, and then, because [INAUDIBLE] in JavaScript, what we're concerned about is a console. So the console is where we can write random JavaScript code and execute it and see what happens. So JavaScript is, like I mentioned, a programming language. It comes with its basic data types, such as numeric data type. So you can have something like five. And you can store this in a variable. So I've looked at variables previously. So say I said x equals 9 and I can say y equals 10. And I can do basic mathematics operations with it, which is, in this case, I just executed x times y, which gives me 90. And then we could also have strings types. So let's say I had a name. in this case, my name is Sela, and I can store that. And one function that we're going to consistently use-- we're using JavaScript. It's a console.log. And what console.log does is it simply prints out something to the console. So in this case, if wanted to print out my name, I can simply print out a console.log name. So in the console, you can also execute some basic JavaScript functions. So one function you've probably encountered is the alert. So alert is meant to pop up some window. So if I run this, so we do see a window pop up there. And it says "Greetings." And I could do something. So let's say I didn't want to say "Greetings," and I actually want it to say "Greetings to Sela." So I can use the plus sign, which really just concatenates some strings. So in this case, I have the greeting string and I have the name string. And I can execute the strings together and I get "Greetings, Sela." And then one other nice feature that you can probably relate to with Python is as opposed to me using this plus sign to concatenate my strings, I can actually input Format My String to have the value that I wanted to have. So in this case, we're looking at Greetings. And then I want it to have Sela in it. So I have Greetings that I can use the dollar sign with the curly braces and have the name, which I want input there. And then Close. And then we execute that, I still get the same thing that I had. So Greetings plus name is the same as me having Greetings, the last line, open curly braces, the value that I want to have, close curly braces. And then one other thing that also changed is instead of me using the quotation marks, the quotes, I'm now using the backtick. So you can find the backtick right before 1 on your keyboard, if it's on my keyboard. I'm not sure about the Windows keyboard. So anyway, so these are some basic things you can do in the JavaScript console. And so we can also go over to [? enact your ?] Script and see how we can execute JavaScript code from there. So I'm going to open up an external page. Sorry. Give me a moment. OK, so here, I want us to go over some other data types that we have in JavaScript. So we looked at numeric data types. We looked at strings. So one of the important data type that I think you need to know for JavaScript is the object data type. So an object, really, you can think about it as something that has properties and methods. And then in here, I have created a bunch of objects in which I have listed some key value pairs. So if familiar with Python, this kind of looks similar to the dict data type, where you can assign values to keys. In this case, I have a list of students. And then for each student, I have different properties, which is I have a name, I have a house, I have a major, and then I have a number of students in there. So we could go over create an object in JavaScript. So let's say I decided to create a new student object, and then I'll say New Student. It goes to open, close curly braces. So similar to how you'd initialize in dict Python. And then I can assign values and properties to this new object. So I can say I want my new student to have a name of, say, John. And then I can say, let my new student be a member of the house. I'll say [INAUDIBLE] again. And then I can say let my new student be a mechanical engineering major. So I have now created a new student. So I can console.log the student. And so if I opened up my browser-- so I have this JavaScript that I have defined, which I have [INAUDIBLE].. And then this JavaScript, I have included it in this HTML page, which is just basics. So I have this particular page open here. And then if you notice, on this particular page, I still have the console window open. And if I had to refresh this page, I have my new student. That's here. And OK, so I'm actually printing the student itself. So if I look at this, I have the new student who I have console.log in. So I said my new student is going to have the name John, house [INAUDIBLE] major ME, and then we see that happen there. And I'm also printing out all the students that I have. So my student array has the predefined students that I made. And then we see the predefined students in there. And so if I wanted to add this to my array, I can simply say-- in My Students, I am going to push my new student. So we notice array now changes. Instead of me only having two objects in my array, I now have three objects with all of them in there. Now, let's say I didn't want just print out all of this. Let's say I wanted to go over all my students, iterate through all of them. So in this case, I want to look over my students and maybe print out a particular value for my students. So we can, of course, use a for loop. So we're familiar with for loops. And I'll probably use a different one that we haven't used so much, where we can have students. And then on students, I can call the loop for each. So what students loop for each does is it's going to go through every student and then return the current student that I'm at. So these return the current object that I'm at in my array. And then for this object that I'm returning, I'm going to define a function. So I'll say, student, where student is a current student I'm looking at. And then does something with the students. So let's say all I want to do is just print out the names of my students. So I'm going to say student.name, because of the log student.name. And then if we save this, we notice, in our browser window, I print out all my student names. Sela, Jim, and John. So what students.dot for each did, so it goes over, like I said. So it's going to iterate over all my students, and then it's going to return every single item that's in my student array. So in this case, every item in my student array is an object. So let me show you that. So we can print out the student itself. And if I save this-- so you notice student is actually an object. Then I can do anything I want with that current item I'm at in the array, or I have that. So what I have inside my dot for each is this function here. So this function is a function that's code. Each time I go, I go to the next item in my array. And then we can use some nice JavaScript syntax to actually make this more concise. So notice here, I have function defined, but then I have no name. So basic construct fully functioning JavaScript is you declare that I'm beginning a function. Then you put some name, and then some arguments, parentheses, in your brackets, and then have the curly braces. But then in JavaScript, we are not mandated to actually provide a function each name. So in this case, I can do away with the func name and then just have a function. So in this case, this is an anonymous function because I really haven't given it a name. So what I have inside here, inside my [INAUDIBLE] is an anonymous function. Now in this case, I have an anonymous function. So with [INAUDIBLE] of JavaScript, they decided, well, I'm not giving this function a name. I might as well just not have it there. So then they introduce another syntax, which is the fat arrow, where I do it with a function. And then, instead of me having function student, I just do student, which is the parameter, the argument that I'm positing, which is going to pass into my function, and then have this fat arrow. So we're if we run this code, it's still as same thing. So it's just more concise, and you'll probably come across this notation, this type of syntax, from time and again. And so they just didn't end there. They went further. And then they said, well, I have a function. And so my function takes in one argument, which is student, and it simply has one-- it just returns one thing. And the only thing it returns right now is just console.logs. In this case, print out the name. For this array, I, as well, don't need to have my curly braces here, and so I can just do away with them. And if I run that, so notice, it still does the same thing. So the function that we had before was just really just like bin string, and then now I have this more concise function. So that's on objects and functions and some function syntax. So we are now going to move on to JavaScript as a DOM, so going over some basic constructs in JavaScript. And so now I want us to look at using JavaScript on the client side, which is really using JavaScript to manipulate the DOM. So I mentioned earlier that JavaScript was initially built to run in browsers. And then what JavaScript did for us, and still does for us, with it being able to write in process, is I can actually add some dynamic functionality to the different HTML pages that I have in my browser. Now, the question is, how does JavaScript manipulate? So it's a programming language that's going to work with the different elements you have in your browser. So in this case, an HTML page. So the question is, how does JavaScript actually manage to help us manipulate our HTML pages? So in understanding that, we come across the DOM. So the question is, what is a DOM? So to put it simple, the DOM is a programming interface for HTML and XML documents. So what does that mean? So the DOM is simply that. It's an object that enables other programming languages to interact with my HTML or XML documents. So in this case, we'll be focusing mainly on HTML documents. And so what a DOM does it takes an HTML page. It presents it as a single object in universal format, such that any programming language that I wanted to use that provides an interface with DOM objects can use it to manipulate DOM. So with recent lectures, we've been looking at working in the web, medium web applications, working in JavaScript. So we're just going to quickly go over some of the methods that we've encountered with using JavaScript to access and manipulate the DOM. So I singled out some. So in this case, we have document.getElementById, which has been in use for quite a while. And then document.querySelector, document.querySelectorAll are really some methods which I did later on. So maybe not as popular, but still very useful. And I will show you how you can-- we'll go through examples of how you can use them. Like, say, how can I use document.querySelector in place of document.getElementById. So open up some examples again and then we'll go through that. OK, so now I have a new HTML page. So I have it open here also. So this is my DOM page. It really just has one header tag, my one H1 tag. And in this HTML page, I have linked another JavaScript file. Sorry. That's the wrong one. So presently, my JavaScript file is empty. So I'm going to populate it with some basic JavaScript things we can do with a DOM. So let me close this one. We don't need this. So like I said, JavaScript is able to access and manipulate some elements. And so we'll start off with something basic that you can do with the DOM. So you only have one tag in here, or one header tag, which is my DOM page. And let's say you actually you wanted to create a new element in your DOM and then add it to your DOM and have it displayed. So of course, the simple way to do this is you could just literally go into your HTML page and say, I'm going to add-- so to add a paragraph, I'm going to add a paragraph with some stuff. But then when you stop programming, you'll probably find that some things that you add to your page are not needed when your page is actually loading, but then you probably want to provide that information after your page is loaded and you've maybe gotten some information from a user. So let's see how we can add a single paragraph in my HTML page. So let's start with let p equals-- so I'm going to use my document object, which provides me some methods that I can use to achieve what I want. So in this case, all I want to do is to create an element. So I'm going to make an element, and in this case, I want to create a paragraph. That's going to be a p element. And then to my paragraph, I can add some content. And so let's say let p dot text content equals the CS50 is awesome. So I've created an element, which is a paragraph. I've added some content to my paragraph. And now, I really want to stitch this element that I've added to this document that I have. So in this case, I'm going to call my document Object again. And then, say, from my document in here, I want to get the body. And then to my body, I want to append some child. So in this case, a child I want to append is a new paragraph element that I've created. So I can say this and see what happens. OK, so right now, I'm in my console. So if you have your element-- so it's not just my paragraph, which is supposed to say "CS50 awesome" also hasn't been added. And one use for debugging tool I like using when I'm using JavaScript is uses a console. So the console is going to tell you you have some error. Can read property of append child of null? And you can actually click on this when you open up your option JavaScript code, and show you what an error is. And if you hover over the cross sign, you see error it is, which is can I trade property of append child of null. So what this is telling us is you're trying to append some child to something which is null. So why do we think this might be the case? Why are we getting some null object that we're trying to append to? So if we go back to our index on HTML, we're notice-- so we have this script, this JavaScript, that we have included in our HTML page. And so let's imagine we are a browser and are trying to load up this HTML page with this JavaScript. So I get this HTML page. And then before loading up my [? text ?] HTML page, I have this JavaScript. And this JavaScript is accessing some elements that are in my HTML page, but then I haven't finished loading my entire page. So this might be a potential reason for why I get this error. I'm saying, from my document, get the body element. So I know my browser is telling me, saying, I don't know what your body element is. Because I really haven't finished loading this document so I don't have that body element that you're looking for. So this is why, probably, you've noticed with the previous work you've been doing, you have your script at the bottom. So let's say I could put my script here. And if I run this, it actually gives me what I want. I have my DOM and then I have my CS50 is awesome, and it runs, right? So now, I have this DOM. This particular document has been loaded. The different elements that I have in there have been added to my DOM. And so now, when my source [? min ?] tries to access some element in my DOM, defined in my DOM, it now doesn't draw an error. So one other way we can deal with this is I can still have it there. And then I can use one method provided to us by the window object, which is you can define a function and say, I only want to load this function when my page is actually done loading. So in this case, I'm going to call window.unload. So what window.unload means is simply saying when I'm finished loading my entire window, I can define some anonymous function. So it can have it there and there. And then closes. So when we save this to-- sorry, excuse me. So when we save this, we notice it runs it on an error, which is, of course, as explained, this is now executing after my entire window is actually loaded. So when I tried to access my documented body, you want to return it now, it actually turns the element in my DOM. OK, so those are some basic things. Then it said it also wanted us to look a bit into document.getElementById and document.querySelector and SelectorAll. So let's add some more things in my HTML. So let's say I had some paragraph. Let this paragraph be 1. And then you [INAUDIBLE] So I've added some your paragraphs, which, really, are just numbers. So let me try to minimize this. So I have these numbers, and then let's say I now wanted to, say, modify, or get some number, or I mean, or get some paragraph from my HTML page. So one way of doing this is using my document.querySelector. And then that result equals that. And then let's log this result. So if I say this and run this, we can see what happens. So in this case, come and save. And so I can go to my console and see what I'm actually printing out. So in this case, I have this paragraph. So I documented query selector p, right? So in this case, what this does is it's going to go into my DOM, select any element that has the p tag in it, and then I finally pick it out. So it prints out the entire thing, which is that. So one thing that you notice is I actually defined a bunch of programs. So I actually have three programs. I have three p tags in my DOM. But then what document.querySelector does is it's going to get the first matching element with the selector I have put here. So let's say I just wanted to have-- I would select this p with the 1. One way to go about this is I can assign an ID. Say, let this have an ID of P1. And then just so we can look at the different flavors of this, let's also have a class definition. Let's say this is class P2. And so if we remember in CSS, if I had some CSS file that I've created, then I want to assign attributes to some element based on an ID, I would use a pound sign. So I'd add a pound in front of that, saying this is actually an element and not some-- I mean, this is actually an ID and not some element tag. So in case, the idea I used here was P1. So I can add it there. And so we notice, it comes here is actually have the ID P1 and the content unit. We can do something more. Let's change the content of this program. This program just has one, and let's say you wanted to change it to result dot, in an HMTL, and I can say CS50 is great. And if I say this, you notice my P1 node changes to that. So I had done something else. So I also added a class here. Now, let's say you don't select an element based on its ID or its tag. You want to select this element based on its class, right? So again, like we had in CSS, if you wanted to select an element based on its-- let's call this result 2-- if you need to select something based on its class, instead of you having the pound sign, you'd have the dot. And this gives my class name as P2. So if I print my result 2 and I save this-- So you notice, in our console, what we get printed out is my result P2. So this is selector, document.querySelector, and then we just do one last example of SelectorAll. And let's say, in this case, I wanted to return all my p tags, every single element I have in my DOM with the tag p. So one thing I could use is I can use my Document.querySelectorAll and then add my p tag there. So in this case, if I printed out my results and I say Save. OK, so what you notice is return some node list. So in this case, if we expand this, I have my p with ID P1, then I have my p with class P2, and then I have my other p's. OK. And we can look at the contents, too. OK. So the unfortunately, that didn't give me the content that I was looking for. It was a bit too much. But you could probably scroll through to see which p tag each of them belongs to. So what Document.querySelector does is it is going to select all my p tags, and then it's going to return a list. So in this case, it's going to return an array of all the different p tags that I have in my DOM object. So probably won't go so much into DOM manipulation. We have covered a lot of that in class already, so I'll move on to the next part of the seminar. OK. So finally, I want us to look at a single-threaded asynchronous. So when I ask the question, what is JavaScript? So I mention single-threaded, asynchronous language. And like I said, I didn't go into detail then, would come to it. And now we have come to it. So now, the question is, what does it mean when someone says JavaScript is single-threaded? What does it mean when someone says JavaScript is in asynchronous language? So in plain, simple words, what does it mean for JavaScript is single-threaded? That means JavaScript, in its runtime, can only do one thing at a time. So what does it mean, really? So I'll give an example of humans. So humans are multi-threaded machines, if I should put it that way, in that you can say, I can talk on the phone and run. I can listen to something and work on my laptop. So I am performing more than one task. I have the ability to perform more than one task at any given time. But then with JavaScript, it just can't do that. I can perform a network code in JavaScript and be doing some algebra calculations all at the same time. With JavaScript, when it executes in its runtime is when you give it a list of tasks to do, it is going to go over each task one at a time. So this will be different from some languages that you are familiar with. For example, Python. Python is a multi-threaded language. It can multitask. It can do many things at one time, which is a useful feature, because sometimes you might have something that takes long in the network and you do not want that to stall every other thing that you want to execute in your code. So another perception of it, what does it mean to be single-threaded? You also find many people say this, which is JavaScript has a single code stock. And so we'll look into what, really, is a code stock? So I have a simple definition for it, which is a call stack is data structure that is going to record where we are in the program. So I put up this diagram, and we probably might have looked at this when we looked at our memory management inside our computers. So here, we have the JavaScript environment. So we have the JavaScript runtime engine, which is really where my JavaScript code is executed. So in my runtime engine, I have the heap, where memory allocation is going to take place, and I have a stack. So in my stack, I have a list of functions. And how the stock adds is that whenever I call a function, function is going to be popped onto the stack. And the function is only popped off the stack when my function actually returns. And so I have an example of this, and you'll see that in action. And then the whole JavaScript environment is not just made of the JavaScript runtime engine. So you have some other features that are added to this environment. You have things like web APIs, and then you have the event loop and the callback queue. And again, we're going to come back to this soon. Excuse me. OK. So like I mentioned, JavaScript only has once you go call stack. So it only has one single thread, where it's going to be popping off and adding functions onto. So everything is going to be happening by synchronously, one at a time. So in this case, I have three functions in my stack. So I have mean. I have show text. Set time out. The total [? C ?] actually won't stay on that stack. But then if I have defined a bunch of functions, they're all going through my stack, and then JavaScript is going to execute one function at a time. So I said this may be problematic if you have something that goes on for a long time because it is going to block everything else from happening. And if this was, say, in your web browser and you have using JavaScript, you define some function that blocks out every other JavaScript code. That would provide bad user experience, in that every other thing that the user can do in your browser will be stopped until that one function that's really slow finally completes. and then other features can actually be accessed. So the question is, how does JavaScript manage to get around this? And so now this brings us to JavaScript being in asynchronous language. It is, like I mentioned, in JavaScript runtime, where your JavaScript code is actually going to be executed, can only do one thing at a time. But then, because your browser adds these extra features, such as your web APIs or event loop, JavaScript can do other things. And then we'll see why. So we'll come back to this and then I'll give an example why the web API helps us. So again, open up this example. And then I found this nice visualizor for the JavaScript environment and I'll use this. OK, so firstly, I want us to visualize a call stack. What really is a call stack and what does it mean to pop-- I mean, to put a function on it and pop a function off? So if I run this, what we see is I have my-- pause this here. So the highlighted means the functions that are being executed. So here, I have this function at the top, which cannot be seen, unfortunately, because of that. So I have a function for which returns another function bar, which returns [INAUDIBLE],, which returns another function, returns another function, all the way up to bar z, which is going to-- so all of the devices, which is finally going to print out some high statement, and then finally return. So I have defined this function, and then among this function, you have this main function, which we're at the bottom. The main cause the function for, and then after the function for has returned, main is finally going to return some 3 plus 5 value. And so the first function to be code here-- so notice, all of these are just function definitions that haven't yet code any function, except within the function, within functions themselves. But the first function that I'm going to call here is my main function. So console.log is going to call main, and then main will execute this. It's going to call for. And then for is basically calling these other functions. And so this is what we notice happening. So as its function is code, it's going to be popped. So this function is code. It's going to be popped into the stack, and so the stack just keeps building. It keeps going and going and going until the final function returns. So in this case, bar z returns by calls of the plugin [? high. ?] And then once bar z returns, then the other functions. So once bar z returns, then bar z's finally popped off the stack, and then the other functions can now get popped onto the stack. So if I do this, so you notice now my stack starts decreasing. So this is like what's happening in my JavaScript runtime, where I'm just having functions pile up. So I prepared an example to simulate what I mean by if you have one function that's blocking everything else on your call stack, and what that would imply. So let's open up an example. So I have another page, which is just a [INAUDIBLE] page. So in this case, I've linked the first JavaScript file that I have here. And so in this JavaScript file, we see it does the first thing, which is it prints out [INAUDIBLE] then enters this while loop, which goes on. And then this while loop just prints out [INAUDIBLE] a couple of times. And then when that while loop done, prints out console.log. So if I run this in here-- OK, it's already been run, but let's see what's happening in the console. So you go in. OK. So what we notice is I start with I'm starting. Then I am the second that's being printed out. And the last, now that's waiting. So it will not print out until I am done with my while loop. So say, in this case, you had some other JavaScript functionality beneath this. What that means is everything that you have occurring after your while loop is now just going to stall and just wait for you to finish printing out this while loop. So of course, this is not a real-life kind of scenario, because unless, otherwise, someone wouldn't really want to print out, I mean, that statement forever. But this is just to show so you can have some things like this that are in your code and then would prevent other things from running. So I keep on giving an example of network codes just because network codes, such as, say, me getting something from some API, would take a long time to execute. So let's say you had an network code here, which takes forever, that means every other thing that you want to do would have to wait for that network code to complete, and then you do it. But then I said JavaScript has found a way to get around this, to execute things more than once using asynchronous functions. So we're going to open one. So in this second example, I have replaced that while loop that I had with a setTimeout function. So a setTimeout is something provided us through the web APIs. And what setTimeout does, so setTimeout accepts a function, a callback function, and your delay value. So in this case, what it means to be a callback function is I am this function that's going to be code when this thing is finished with what it's supposed to do. So let me write it out as it would. So it's supposed to have a function delay. So the main object of setTimeout is it's going to create some delay in what you're doing. Now, the purpose of the callback function is it's going to stipulate what is going to happen when your setTimeout has actually finished. So in this case, when your time has run out. So in this case, I have set a time of 10,000. And what I'm saying is create this delay of 10,000, and then when you're finally done, I want you to execute this function, which is just console.log in and the callback function. So let's see how this works. So if I run this, so I'll go to into the index of this. And let's link, instead, my async. OK. So let's refresh that, see what happens. OK. So it's taking a while. Let me reduce the time here, maybe that much. OK. So it's taking a while, but we see what's happening. So in this case, the first thing that I do is I code I'm starting. Then I put a time out, and then I finally code the console.log and the last function. But then if we see the order in which they executed, we notice the first thing that's executed is I'm starting, then the last function, and then, finally, the callback. So setTimeout is an asynchronous function, which is really going to say-- so you're going to cause a time out. And then setTimeout is going to run in its web API. And then when it starts running in its web API, I will not have setTimeout on my call stack. And so what does it mean to push out the time out of the call stack? That means I can add my console.log onto the call stack and actually execute it. So notice, so if I refresh this, I don't have to wait for setTimeout to execute for me to actually continue to [? kick ?] in my other code. And so this is how JavaScript manages to get around-- deal with its single-threaded nature, by creating this asynchronous functions, which do not block other functions from executing, but simply are going to execute when I'm done. So in understanding the synchronous functions, I think it best to actually see how this happens. Again, we'll go back to this visualizor here. OK. So let's get rid of this previous example. So I started with [INAUDIBLE] And if I have it in here-- so this is [INAUDIBLE]. And you know what [INAUDIBLE] is doing. The first one has really executed, and now I'm just stuck in this while loop, which is running and running until it's done. And then when it's finally done, then execute console.log. But then let's see how this differs from how my asynchronous is going to add. So I paste this in this [? 2, ?] and then I'm going to run this. So we notice something happening. So make this a bit slower so that you see. So we would notice is when I start this, my first function, console.log just pushed into my stack. It executes. Then I get my second function setTimeout. But it's a web API, so it's pushed off the stack. Then it goes into my web API. So since it's pushed off the stack, I am able-- 2 [? plus ?] 2 so I'll probably use a pause. They said I have console.log pushed off the stack, then setTimeout, which is somewhere, maybe a function. So here, it's pushed off the stack. And so because it's pushed off the stack, it's now been executed here in my web APIs. I can have my other function here, which is beneath my setTimeout, come on to my stack. So that means I can execute this console.log function. Now, when you have this setTimeout-- so setTimeout is working in your web API-- you do not want your web APIs to immediately modify your code, or just immediately push code into your stack, in the middle of your code running. So why might that be problematic? So I already have some logical flow of my work. And if my web APIs could randomly push stuff back into the stack, it probably wouldn't be as consistent. The [? floppy ?] work will not be as smooth as you probably would want it to be. So you set up your web APIs randomly pushing stuff back onto your stack. You have this callback queue, which is here at the bottom of the page. And then what this callback queue does is it has this event loop. So when the web API is done running what it's supposed to do, it pushes the particular callback function that you want executed at the end into the callback queue. And then the event loop might have this callback queue saying, when my stack is empty-- that means when I have finished running all my functions in my stack-- I am going to get the first function in my callback queue and put it onto my stack, and then it's going to be executed. So we see how this works. And so I'm running. So setTimeout goes into my stack. It goes to web API. The last function executes. And callback goes into callback queue. It's pushed into the stack. It executes, and then I'm done. All right. And so this is the basic flow of your asynchronous functions and this is how they're managed. This is how they [INAUDIBLE] to do other things whilst they are running, similar to background, but not really in the background. So move on to say my setTimeout is going to run and only executed-- in this case, the callback function will only execute once I'm done doing everything. In this case, executing every other function in my call stack. But there might be instances where you want to stipulate, that I want this particular function to execute only after my synchronous function is done executing. So in this case, say I performed an network code to my Google search. And all I want to do is give my user back the list of [? foods ?] based on their preferences. So I do not want to display something before I actually back my response from Google. So I would want to have a way to stipulate. Say, when I do my search, I only want my display function to execute after my search. And so this is now where the issue of async await and promises coming. So I'll open up an example. So here, you have an example, just to show what I was talking about. So let's go to this and let this be my promise one. So if I open up my HTML page, so I've linked that there. OK, there's my async page. So I have my first promise here. So in this case, my promise-- just give me a moment. OK, so in this case, I have a promise. I mean, I have a promise example, where we start off with the example that I gave, where I have a function, except I want this particular-- in this case, it's not a function. It's some line of code. And I want this line of code to execute when my setTimeout is actually done. So in this case, I set x to be the value that's going to return once I finish running my setTimeout. And then I let my y equals to-- I mean the product of x times 10. So one potential problem that might arise from here is-- so we notice that setTimeout is going to run in the background, and then everything else is going to run as normal. But then we notice, we're using x, which is the value returned from setTimeout. So if setTimeout happened to run for a long time, which it will do in this case, and then I code my y and x. So the most likely thing is I would get an error. And let's see if we can actually see that. OK. So the Python thing actually gives me-- OK, so I'm wondering why it's giving me some random value, which it should not be doing. But I'll, instead, run this in-- OK, so like I said previously, that we can run JavaScript as an [? out ?] browser using Node.js. So if you're going to run JavaScript outside your browser, you'd have to use the Node.js. So I have it installed on my computer. And I think, for now, we use it because it cannot [? sync ?] while my browser gives me some random value. So in this case, I want to run promise 1. OK, so it gives me what I'm expecting. So at the bottom of my terminal here, so I call node and I say node, can you run this particular JavaScript file, where I'm running promise 1. So promise 1 first prints out "I'm starting" and codes this function x and then multiplies x times 10, stores it in y, and then prints out y. One problem that we notice is, especially if I'm stacking, then prints out none, which is not a number, and then ends. So why does it do that? So like I mentioned, you are coding-- you are using x before. Most likely, your setTimeout hasn't actually been executed. So get a certain time, in this case, execute this line of code, it doesn't know what x is. So it just returns not a number. And so then I mentioned promises. and async await. So here, I have described, given a solution, for how you'd get around this problem. I want to set some code to execute after this has finished. So this was the function, the setTimeout that we had before, except now, it's defined inside a promise. So basic syntax for a promise is you have a function and then it has a parameters resolve reject. And then what promise does is it's going to execute a particular function, and then it will either, resolve which it means to give that value. So resolving this case is my callback value. So if my setTimeout is done, it's going to code this function and it's going to code resolve. So resolve means my promise is being executing, and then I'm passing the value. So that's the value it's going to yield. And so if I define this promise, and then I wanted to use it, so instead of we just use an x randomly-- so I define an async function. So in this case, I am defining an asynchronous function. So why do this is a synchronous function come with this keyword here, which is await. And then what await does is it's going to pause my synchronous function and then wait for a promise to finish executing. And then after this particular promise is done, in this case, after my promise resolves, it's going to continue executing its code. So I'll first await the value of my promise. Then when my promise is done, I code y x times 5, and then I console.log y. And so if I code my function-- so in this case, I have [INAUDIBLE].. So this is in promise 2. So if I keep promise 2, I get the value that I'm looking for, which is I'm starting-- then it actually executes 25. So now, this is using async functions. And then one thing that has also been added is, from using async word function, I can also use dot then. So I'm going to use another chain of the promise example, where instead of me awaiting a promise, I'm going to say execute this async function in this promise. Get this promise value. Then when the promise is done, execute this function. It's the same promise from before, and then I define a new-- so I call my promise here and say, perform this promise. When my promise has finally resolved, then execute this function. So I have a function, which takes an x. So whichever value is returned from my promise is assigned to this particular x parameter. And then I can finally multiply my x times 5 and then I can console.log y. And so if I executed this in my node, I still get the same thing. So this is really doing the same thing as my async awaits. So it might depend on my preference. So you might go into Details and actually talk about what is the difference between using dot then and async await. But this is basically how you can handle promises and how you can stipulate when a particular set of code is going to execute with regard to an asynchronous function, where, in our case, asynchronous function is setTimeout. And then, probably, one thing that would want to do from what we learned previously, which is I can actually shorten my function here and say, instead of me having that, I can simply set it to do that and save. And then if I run this, I still get the same thing. So we'll just summarize what we just did, which is what happens when a function for it invites some web API. It's called, in this case. I stated web API, but let's say my asynchronous function is just called. So we'd have that asynchronous function called. In this case, for example, setTimeout. And then that function, we pushed off the stack. Then it's going to be executed somewhere else. And then-- oops, sorry. And then when it's done, my function is going to be added back to my task 2, and then my event loop, which has a task 2, is going to push my function back into the stack when done. And of course, promise is async await, which we just looked at. So this is probably a lot to take in, and I will say probably working with the visualizor, seeing how exactly asynchronous function works, getting more practice into promises and dealing with those asynchronous functions, it's probably a good way to get a handle of this. And this is where, probably, JavaScript becomes tricky to learn, just because of its single-threaded nature and how you have to deal with these async functions. But with more practice, you get a handle of them, and I hope this gave you some place to start. And that's it for this seminar.
B1 中級 JavaScript--基礎知識,Sela Kasepa著。 (JavaScript - The Basics, by Sela Kasepa) 3 0 林宜悉 發佈於 2021 年 01 月 14 日 更多分享 分享 收藏 回報 影片單字