Computer Science

Javascript Event Loop

The JavaScript event loop is a mechanism that allows JavaScript to handle multiple events and tasks simultaneously. It works by continuously checking the call stack and the message queue, and executing tasks in the queue when the call stack is empty. This allows for non-blocking asynchronous programming in JavaScript.

Written by Perlego with AI-assistance

8 Key excerpts on "Javascript Event Loop"

  • Advanced JavaScript
    eBook - ePub

    Advanced JavaScript

    Speed up web development with the powerful features and benefits of JavaScript

    Unlike most programming languages, JavaScript is an asynchronous programming language. More specifically, it is a single threaded, event driven, asynchronous programming language. This means that JavaScript does not idle when waiting for the results of a long-running operation. It runs other code blocks while waiting. JavaScript manages this with the Event Loop. The event loop is composed of four parts, a function stack, a memory heap, an event queue, and the event loop. These four parts work together to handle events fired from operation completion.

    Exercise 16: Handling the Stack with an Event Loop

    To better understand why events in your program are being fired and handled in the expected order, look at the program provided next, and without running the program, write out the expected output of the program.
    For the first 10 steps of the program, write the expected stack, queue, and heap at each step. A step is any time an event fires, the event loop dequeues an event, or the JS Engine handles a function call:
    step 0 stack: <global> queue: <empty> heap: <empty> Snippet 2.5: Call stack example code (starting step) The program is displayed in the following snippet: function f1() { console.log( 'f1' ); } function f2() { console.log( 'f2' ); } function f3() {   console.log( 'f3' );   setTimeout( f5, 90 ); } function f4() { console.log( 'f4' ); } function f5() { console.log( 'f5' ); } setTimeout( f1, 105 ); setTimeout( f2, 15 ); setTimeout( f3, 10 ); setTimeout( f4, 100 ); Snippet 2.6: Call stack example code (program) To demonstrate a simplified form of how the Event Loop handles the stack, queue, and heap while handling JavaScript events, perform the following steps:
    1. Add an event loop stack frame to the stack if a function is called and being handled.Process the function and add the necessary event and handler info to the heap. Remove the event and handler in the next step.
  • JavaScript Concurrency
    In a concurrency context, we're mostly interested in the mechanics that tie all these platform pieces together. Our application is written mainly in JavaScript, and the interpreter knows how to parse and run it. But, how does this ultimately translate into visual changes on the page? How does the networking component of the browser know to make an HTTP request, and how does it invoke the JavaScript interpreter once the response has arrived?
    It's the coordination of these moving parts that restricts our concurrency options in JavaScript. These restrictions are necessary, because without them, programming web applications would become too complex.

    Event loops

    Once an execution environment is in place, the event loop is one of the first components to start. Its job is to service one or more task queues in the environment. Browser vendors are free to implement queues as they see fit, but there has to be at least one queue. Browsers can place every task in one queue if they please, and treat every task with equal priority. The problem with doing so would mean that if the queue is getting backlogged, tasks that must receive priority, such as mouse or keyboard events, are stuck in line.
    In practice, it makes sense to have a handful of queues, if for no other reason than to separate tasks by priority. This is all the more important because there's only one thread of control—meaning only one CPU—that will process these queues. Here's what an event loop that services several queues by varying levels of priorities looks like:
    Even though the event loop is started along with the execution environment, this doesn't mean that there's always tasks for it to consume. If there were always tasks to process, there would never be any CPU time for the actual application. The event loop will sit and wait for more tasks, and the queue with the highest priority gets serviced first. For example, with the queues used in the preceding image, the interactive queue will always be serviced first. Even if the event loop is making its way through the render queue tasks, if an interactive
  • Mastering Node.js - Second Edition
    • Sandro Pasquali, Kevin Faaborg, Glenn Geenen(Authors)
    • 2017(Publication Date)
    • Packt Publishing
      (Publisher)
    synchronously . Now, let's dive deeper into how Node's event loop works.
    Passage contains an image

    Understanding the event loop

    The following three points are important to remember, as we break down the event loop:
    • The event loop runs in the same (single) thread your JavaScript code runs in. Blocking the event loop means blocking the entire thread.
    • You don't start and/or stop the event loop. The event loop starts as soon as a process starts, and ends when no further callbacks remain to be performed. The event loop may, therefore, run forever.
    • The event loop delegates many I/O operations to libuv, which manages these operations (using the power of the OS itself, such as thread pools), notifying the event loop when results are available. An easy-to-reason-about single-threaded programming model is reinforced with the efficiency of multithreading.
    For example, the following while loop will never terminate: let stop = false;setTimeout(() => { stop = true;}, 1000);while (stop === false) {};
    Even though one might expect, in approximately one second, the assignment of a Boolean true to the variable stop, tripping the while conditional and interrupting its loop; this will never happen. Why? This while loop starves the event loop by running infinitely, greedily checking and rechecking a value that is never given a chance to change, as the event loop is never given a chance to schedule our timer callback for execution. This proves the event loop (which manages timers), and runs on the same thread.
    According to the Node documentation, "The event loop is what allows Node.js to perform non-blocking I/O operations — despite the fact that JavaScript is single-threaded — by offloading operations to the system kernel whenever possible."
    The key design choice made by Node's designers was the implementation of an event loop as a concurrency manager. For example, notifying your Node-based HTTP server of network connections to your local hardware is handled by the OS passing along, via libuv, network interface events.
  • Ultimate Node.js for Cross-Platform App Development
    eBook - ePub

    Ultimate Node.js for Cross-Platform App Development

    Learn to Build Robust, Scalable, and Performant Server-Side JavaScript Applications with Node.js

    This diagram represents how the Node.js application works behind the scenes. The V8 engine compiles the code you write in your program, and the application code uses binding to communicate with low-level Node.js components. After events are fired from the application code, they are pushed into the event queue in the order in which they were originally fired from the application. The event loop processes all the events, calls their callback functions, and sends them to worker threads for processing until the event queue becomes empty. After the callback function executes, its callback is returned to the event queue, waiting for the event loop to pick it up.
    Part of your confusion may stem from the choice of technical terms used in the second diagram. If you look closely, under “NODE.JS BINDINGS”, it says “(NODE API)”, which unfortunately are two different things. The Node.js API is the user interface for its built-in libraries, while bindings, from a software programming perspective, are bridges between code written in different languages.
    A client interacts with a web application by sending requests to a web server, which can be non-blocking or blocking. These requests are as follows:
    • Query data
    • Deletion of data
    • Update data
    Node.js takes incoming requests and adds them to an event queue. Requests are then routed through the event loop, one at a time. Make sure your requirements are simple enough to not require external resources. The event loop handles simple requests (non-blocking operations), such as I/O polling, and returns responses to the appropriate clients.
    One thread in the thread pool is assigned to one complex request. This thread is responsible for accessing external resources, completing specific lock requests, and managing computing power, databases, file systems, and more.
    When the task is completed, the response is sent to the event loop and then returned to the client. The following are the core components that make the Node.js framework incredible:
    • V8:
  • The TypeScript Workshop
    eBook - ePub

    The TypeScript Workshop

    A practical guide to confident, effective TypeScript programming

    • Ben Grynhaus, Jordan Hudgens, Rayon Hunte, Matt Morgan, Wekoslav Stefanovski(Authors)
    • 2021(Publication Date)
    • Packt Publishing
      (Publisher)

    10. Event Loop and Asynchronous Behavior

    Overview
    In this chapter, you'll investigate how a web page actually works within the browser, with a special focus on how, when, and why the browser executes the JavaScript code we provide. You'll dive deep into the intricacies of the event loop and see how we can manage it. Lastly, you'll learn about the tools that TypeScript offers you. By the end of this chapter, you will be able to better manage the asynchronous nature of the execution.

    Introduction

    In the previous chapter, you learned the fundamentals of generics and conditional types. This chapter introduces you to event loops and asynchronous behavior. However, before you proceed with learning these topics, let's have a look at a hypothetical scenario to really understand how synchronous and asynchronous executions work.
    Imagine a small bank that has a single teller. His name is Tom, and he's serving clients all day. Since it's a small bank and there are few clients, there's no queue. So, when a client comes in, they get Tom's undivided attention. The client provides all the necessary paperwork, and Tom processes it. If the process needs some kind of outside input, such as from a credit bureau or the bank's back-office department, Tom submits the request, and he and the client wait for the response together. They might chat a bit, and when the response comes, Tom resumes his work. If a document needs to be printed, Tom sends it to the printer that's right on his desk, and they wait and chat. When the printing is done, Tom resumes his work. Once the work is completed, the bank has another satisfied client, and Tom continues with his day. If somebody comes while Tom is serving a client (which happens seldom), they wait until Tom is completely done with the previous client, and only then do they begin their process. Even if Tom is waiting on an external response, the other client will have to wait their turn, while Tom idly chats with the current client.
  • JavaScript Unlocked
    http://www.creativebloq.com/web-design/responsive-web-design-tips-bbc-news-9134667 ). We extract the components of an application required for core experience and load them first. Then, progressively we add an enhanced experience. As for JavaScript, what we have to care the most about are nonblocking flows. Thus, we have to avoid loading scripts synchronously prior to HTML rendering, and we have to wrap all long-running tasks into asynchronous callbacks. This is something that you most probably already know. But do you do it efficiently?
    In this chapter, we will cover the following topics:
    • Nonblocking JavaScript
    • Error-first callback
    • The continuation-passing style
    • Handling asynchronous functions in the ES7 way
    • Parallel tasks and task series with the Async.js library
    • Event handling optimization

    Nonblocking JavaScript

    First of all, let's look at what really happens when we do things asynchronously. Whenever we invoke a function in JavaScript, it creates a new stack frame (execution object). Every inner call gets into this frame. Here the frames are pushed and popped from the top of the call stack in the LIFO (last in, first out ) manner. In other words, in the code, we call the foo function and then the bar function; however, during execution, foo calls the baz function. In this case, in the call stack, we have the following sequence: foo , baz , and only then bar . So bar is called after the stack frame of foo is empty. If any of the functions perform a CPU-intensive task, all the successive calls wait for it to finish. However, JavaScript engines have Event Queues (or task queues).
    If we subscribe a function to a DOM event or pass a callback to a timer (setTimeout or setInterval ) or through any Web I/O APIs (XHR, IndexedDB, and FileSystem), it ends up in a corresponding queue. Then, the browser's event loop decides when and which callback to push in the callback stack. Here is an example:
    function foo(){ console.log( "Calling Foo" ); } function bar(){ console.log( "Calling Bar" ); } setTimeout(foo, 0 ); bar();
    Using setTimeout( foo, 0 ) , we state that foo shall be called immediately, and then we call bar . However, foo
  • Secrets of the JavaScript Ninja, Second Edition
    We know that the time-out callback is never guaranteed to execute exactly when it’s fired. Rather than being fired every 10 ms, as the interval is, it will reschedule itself for 10 ms after it gets around to executing.
    All of this is incredibly important knowledge. Knowing how a JavaScript engine handles asynchronous code, especially with the large number of asynchronous events that typically occur in the average page, creates a great foundation for building advanced pieces of application code.
    With all that under our belts, let’s see how our understanding of timers and the event loop can help avoid some performance pitfalls.
    13.2.2. Dealing with computationally expensive processing
    The single-threaded nature of JavaScript is probably the largest gotcha in complex JavaScript application development. While JavaScript is busy executing, user interaction in the browser can become, at best, sluggish, and, at worst, unresponsive. The browser may stutter or seem to hang, because all updates to the rendering of a page are suspended while JavaScript is executing.
    Reducing all complex operations that take any more than a few hundred milliseconds into manageable portions becomes a necessity if we want to keep the interface responsive. Additionally, most browsers will produce a dialog box warning the user that a script has become “unresponsive” if it has run nonstop for at least 5 seconds, while some other browsers will even silently kill any script running for more than 5 seconds.
    You may have been to a family reunion where a garrulous uncle won’t stop talking and insists on telling the same stories over and over again. If no one else gets a chance to break in and get a word in edgewise, the conversation’s not going to be pleasant for anyone (except for Uncle Bruce). Likewise, code that hogs all the processing time results in an outcome that’s less than desirable; producing an unresponsive user interface is never good. But situations will almost certainly arise that require us to process a significant amount of data, situations such as manipulating a couple of thousand DOM elements, for example.
  • The JavaScript Workshop
    eBook - ePub

    The JavaScript Workshop

    A New, Interactive Approach to Learning JavaScript

    • Joseph Labrecque, Jahred Love, Daniel Rosenbaum, Nick Turner, Gaurav Mehla, Alonzo L. Hosford, Florian Sloot, Philip Kirkbride(Authors)
    • 2019(Publication Date)
    • Packt Publishing
      (Publisher)
    Linux Terminal would simply read the contents of a directory on the hard disk and display the details of those files and directories within the Terminal window. The Linux operating system is built on the premise of such very small and simple applications working together to create a much larger ecosystem. The converse of this may be modern multiplayer video games, which typically react to user interaction and receive streamed data from remote locations. The former of these concepts can be considered much like a function: input enters from the top and is output somewhere within the body, typically, the end of the function.
    JavaScript applications can facilitate both ends of this spectrum, and indeed, anything in between. Modern browsers are now fully capable of providing the foundations for immense and processor-intensive 3D multiplayer games, responding to data from numerous sources, but JavaScript is also frequently used for the simplest of tasks, such as formatting a string or rounding a number .
    At the core of all of these applications are events . Events, conceptually speaking, are triggers that execute code. This might, for example, be the ready state when a page has finished loading or a mouse event when the user clicks an element within the page. Typically, without events, functions won't know when to execute and, therefore, nothing can happen.
    Throughout this chapter, we will examine the options JavaScript provides for listening to and handling different types of events within the browser environment.

    Event Types

    An event is simply a notification or a "triggered " alert within the JavaScript runtime. These notifications can represent practically anything but are a means to invoke one or more of your own functions when such an event occurs.
    When a web page loads, the browser will typically display content as soon as it is available. This means some content will be presented to the user before the entire page has finished downloading. The browser does this to prevent long-loading assets from withholding other content from being available to the user.
    Now, imagine you want to invoke a function immediately within a web page to rotate an image. JavaScript code embedded into a web page is able to run immediately once it has been parsed by the JavaScript engine, which could possibly be before the image in question is available. To overcome this conundrum, JavaScript provides an onload
Index pages curate the most relevant extracts from our library of academic textbooks. They’ve been created using an in-house natural language model (NLM), each adding context and meaning to key research topics.