When JavaScript is running in Node on a back-end server, it needs to do very different things than what JavaScript would need to do if it's running on the browser on your computer, free to access a website. In order to do this, that's when the runtime implements these APIs, and to do that, in your low-level code, you could define a function, and then after that, you would do two things. You would define a binding, which allows you to expose that function that you write in C++, or C, or another low-level language, and then two, after you define the binding, you can then call it in JavaScript. So we talked about Node in the browser. What are some common runtime APIs for Node? In Node, you want to be able to access the file system with FS, you want to get system-level info like CPU or memory info, you can do that with the OS API, and then you also want to create services using HTTP and HTTPS. If you are using JavaScript on a browser, and you're on a browser runtime, you want to do very different things. You want to be able to interact with HTML via the DOM, you want to make network requests using Fetch, and then you want to store things in your browser using local storage and session storage. There are a lot of other runtimes and engines. This is not a complete list, but a few runtimes and engines you should know about. There's Deno, Bun, and Electron, those are runtimes, and then for engines, there's V8, there's JavaScript Core, and then there's V8 Plus Chromium.
So far, we've covered the two things that the runtime does. The third most important thing, not the most important thing, but a very important thing, is the event loop. What is the event loop? Well, the runtime used the event loop to determine when to run your code. The event loop is just additional code that's part of the runtime that you write, and some event loops are even libraries. Like Node uses the liduv library of the event loop, which is a C++ library that you can embed in your own code. In order to understand what the event loop is doing, there are four components that we want to keep in mind. There's the actual event loop itself, which is the code that's written in the runtime. There's a call stack, which is where your code is actually executed, and then there are two queues, the microtask queue and the task queue, that is also referred to as the macro task queue. And these all combine with the runtime, the engine, and all the other components to execute your code. So on the right we have pseudocode that's showing what happens at a high level. What's happening is that the event loop checks to see if the call stack is empty. If it is, it takes everything from the microtask queue and places that onto the call stack for that code to be executed. And then once all of the items from the microtask queue are done, it takes one item from the task queue or the macro task queue, puts that into the call stack to be executed. So the event loop is a continuously running process you can think of that monitors the call stack and the queue to decide when code is executed. And this is the primary way JavaScript behaves asynchronously, even though it is single-threaded.
To recap, the engine is a low-level code that executes JavaScript. Similarly to the engine, the runtime is also low-level code and it allows your code to be run. Thank you for listening to our talk.
Comments