JavaScript Concurrency: Build better software with concurrent JavaScript programming, and unlock a more efficient and forward thinking approach to web development
By Adam Boduch
()
About this ebook
About This Book
- Apply the core principles of concurrency to both browser and server side development
- Explore the latest tools and techniques at the forefront of concurrent programming, including JavaScript promises, web workers, and generators
- Learn how concurrent and parallel programming can help you tackle the challenges of fast, data heavy web development
Who This Book Is For
JavaScript Concurrency is written for any JavaScript developer who wants to learn how to write more efficient, powerful, and maintainable applications that utilize the latest developments in the JavaScript language.
All aspects of concurrent, asynchronous, and parallel programming are covered from first principles and by the end of the book you’ll be able to create a fully-worked application that leverages all the topics covered in the book.
What You Will Learn
- Understand exactly how JavaScript works in a web browser environment, and how these mechanisms power our event-driven JavaScript code
- Use promises to turn complex synchronization scenarios into readable and maintainable values
- Compute values lazily and avoid unnecessary memory allocations using generators.
- Write concurrent code that doesn’t feel like concurrent code by abstracting away boilerplate chores
- Leverage true hardware parallelism with web workers to get a better performance
- Get to grips with the NodeJS model of concurrency and learn why it’s good for I/O-intensive web applications
In Detail
Concurrent programming may sound abstract and complex, but it helps to deliver a better user experience. With single threaded JavaScript, applications lack dynamism. This means that when JavaScript code is running, nothing else can happen. The DOM can’t update, which means the UI freezes. In a world where users expect speed and responsiveness – in all senses of the word – this is something no developer can afford.
Fortunately, JavaScript has evolved to adopt concurrent capabilities – one of the reasons why it is still at the forefront of modern web development. This book helps you dive into concurrent JavaScript, and demonstrates how to apply its core principles and key techniques and tools to a range of complex development challenges. Built around the three core principles of concurrency – parallelism, synchronization, and conservation – you’ll learn everything you need to unlock a more efficient and dynamic JavaScript, to lay the foundations of even better user experiences.
Throughout the book you’ll learn how to put these principles into action by using a range of development approaches. Covering everything from JavaScript promises, web workers, generators and functional programming techniques, everything you learn will have a real impact on the performance of your applications. You’ll also learn how to move between client and server, for a more frictionless and fully realized approach to development. With further guidance on concurrent programming with Node.js, JavaScript Concurrency is committed to making you a better web developer.
The best developers know that great design is about more than the UI – with concurrency, you can be confident every your project will be expertly designed to guarantee its dynamism and power.
Style and approach
Beginning with the fundamentals of concurrency and how they apply to JavaScript development, the book then takes you through the relevant constructs that will help you implement concurrent code. You’ll learn how even the most abstract and theoretical aspects of concurrent programming help you solve real world challenges, with clear and practical demonstrations that show you how concurrent JavaScript will make you a better developer.
Adam Boduch
Adam Boduch has been involved in large-scale JavaScript development for nearly 15 years. Before moving to the frontend, he worked on several large-scale cloud computing products using Python and Linux. No stranger to complexity, Adam has practical experience with real-world software systems and the scaling challenges they pose.
Read more from Adam Boduch
jQuery UI Cookbook Rating: 0 out of 5 stars0 ratingsReact and React Native Rating: 4 out of 5 stars4/5React and React Native: Build cross-platform JavaScript and TypeScript apps for the web, desktop, and mobile Rating: 0 out of 5 stars0 ratingsLo-Dash Essentials Rating: 0 out of 5 stars0 ratingsLearning jQuery 3 - Fifth Edition Rating: 0 out of 5 stars0 ratingsJavaScript at Scale Rating: 0 out of 5 stars0 ratingsFlux Architecture Rating: 0 out of 5 stars0 ratings
Related to JavaScript Concurrency
Related ebooks
The JavaScript Journey: From Basics to Full-Stack Mastery Rating: 0 out of 5 stars0 ratingsNode.js Blueprints Rating: 0 out of 5 stars0 ratingsJavascript Mastery: In-Depth Techniques and Strategies for Advanced Development Rating: 0 out of 5 stars0 ratingsYour First Week With Node.js Rating: 0 out of 5 stars0 ratingsUltimate Node.js for Cross-Platform App Development Rating: 0 out of 5 stars0 ratingsNode Web Development, Second Edition Rating: 0 out of 5 stars0 ratingsMastering JavaScript Promises Rating: 1 out of 5 stars1/5Learning Reactive Programming with Java 8 Rating: 0 out of 5 stars0 ratingsModern Web Development with Go Rating: 0 out of 5 stars0 ratingsJavaScript at Scale Rating: 0 out of 5 stars0 ratingsNoSQL Essentials: Navigating the World of Non-Relational Databases Rating: 0 out of 5 stars0 ratingsUltimate Ember.js for Web App Development Rating: 0 out of 5 stars0 ratingsGetting Started with Meteor.js JavaScript Framework - Second Edition Rating: 0 out of 5 stars0 ratingsUltimate Microservices with RabbitMQ Rating: 0 out of 5 stars0 ratingsUltimate Git and GitHub for Modern Software Development Rating: 0 out of 5 stars0 ratingsHow Computers Make Books: From graphics rendering, search algorithms, and functional programming to indexing and typesetting Rating: 0 out of 5 stars0 ratingsAndroid Studio Hedgehog Essentials - Kotlin Edition: Developing Android Apps Using Android Studio 2023.1.1 and Kotlin Rating: 0 out of 5 stars0 ratingsASP.NET 3.5 CMS Development Rating: 0 out of 5 stars0 ratingsUltimate Selenium WebDriver for Test Automation Rating: 0 out of 5 stars0 ratingsJava with TDD from the Beginning Rating: 0 out of 5 stars0 ratingsJetpack Compose 1.7 Essentials: Developing Android Apps with Jetpack Compose 1.7, Android Studio, and Kotlin Rating: 0 out of 5 stars0 ratingsUltimate Certified Kubernetes Administrator (CKA) Certification Guide Rating: 0 out of 5 stars0 ratingsJavaScript Mobile Application Development Rating: 0 out of 5 stars0 ratingsHTML5 Graphing and Data Visualization Cookbook Rating: 0 out of 5 stars0 ratingsProfessional Java EE Design Patterns Rating: 0 out of 5 stars0 ratingsAdvanced Functional Programming: Mastering Concepts and Techniques Rating: 0 out of 5 stars0 ratingsASP.NET 3.5 Application Architecture and Design Rating: 0 out of 5 stars0 ratingsUltimate Typescript Handbook: Build, scale and maintain Modern Web Applications with Typescript Rating: 0 out of 5 stars0 ratings
Internet & Web For You
Social Engineering: The Science of Human Hacking Rating: 3 out of 5 stars3/5Coding All-in-One For Dummies Rating: 4 out of 5 stars4/5No Place to Hide: Edward Snowden, the NSA, and the U.S. Surveillance State Rating: 4 out of 5 stars4/5The $1,000,000 Web Designer Guide: A Practical Guide for Wealth and Freedom as an Online Freelancer Rating: 4 out of 5 stars4/5How to Be Invisible: Protect Your Home, Your Children, Your Assets, and Your Life Rating: 4 out of 5 stars4/5Cybersecurity For Dummies Rating: 5 out of 5 stars5/5How to Disappear and Live Off the Grid: A CIA Insider's Guide Rating: 0 out of 5 stars0 ratingsPython: Learn Python in 24 Hours Rating: 4 out of 5 stars4/5Coding For Dummies Rating: 5 out of 5 stars5/5Tor and the Dark Art of Anonymity Rating: 5 out of 5 stars5/5More Porn - Faster!: 50 Tips & Tools for Faster and More Efficient Porn Browsing Rating: 3 out of 5 stars3/5HTML in 30 Pages Rating: 5 out of 5 stars5/5The Gothic Novel Collection Rating: 5 out of 5 stars5/5How To Start A Profitable Authority Blog In Under One Hour Rating: 5 out of 5 stars5/5The Beginner's Affiliate Marketing Blueprint Rating: 4 out of 5 stars4/5Beginner's Guide To Starting An Etsy Print-On-Demand Shop Rating: 0 out of 5 stars0 ratingsCoding with AI For Dummies Rating: 1 out of 5 stars1/5An Ultimate Guide to Kali Linux for Beginners Rating: 3 out of 5 stars3/5Six Figure Blogging Blueprint Rating: 5 out of 5 stars5/5Apple Card and Apple Pay: A Ridiculously Simple Guide to Mobile Payments Rating: 0 out of 5 stars0 ratingsCybersecurity All-in-One For Dummies Rating: 0 out of 5 stars0 ratingsJavaScript All-in-One For Dummies Rating: 5 out of 5 stars5/548 Really Useful Web Sites Rating: 5 out of 5 stars5/5Everybody Lies: Big Data, New Data, and What the Internet Can Tell Us About Who We Really Are Rating: 4 out of 5 stars4/5Lying and Lie Detection: A CIA Insider's Guide Rating: 0 out of 5 stars0 ratingsUltimate Guide for Being Anonymous: Hacking the Planet, #4 Rating: 5 out of 5 stars5/5
Reviews for JavaScript Concurrency
0 ratings0 reviews
Book preview
JavaScript Concurrency - Adam Boduch
Table of Contents
JavaScript Concurrency
Credits
About the Author
About the Reviewer
www.PacktPub.com
Support files, eBooks, discount offers, and more
Why subscribe?
Free access for Packt account holders
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Errata
Piracy
Questions
1. Why JavaScript Concurrency?
Synchronous JavaScript
Synchronicity is easy to understand
Asynchronous is inevitable
Asynchronous browsers
Types of concurrency
Asynchronous actions
Parallel actions
JavaScript concurrency principles: Parallelize, Synchronize, Conserve
Parallelize
Synchronize
The Promise API
Conserve
Summary
2. The JavaScript Execution Model
Everything is a task
Meet the players
The Execution environment
Event loops
Task queues
Execution contexts
Maintaining execution state
Job queues
Creating tasks using timers
Using setTimeout()
Using setInterval()
Responding to DOM events
Event targets
Managing event frequency
Responding to network events
Making requests
Coordinating requests
Concurrency challenges with this model
Limited opportunity for parallelism
Synchronization through callbacks
Summary
3. Synchronizing with Promises
Promise terminology
Promise
State
Executor
Resolver
Rejector
Thenable
Resolving and rejecting promises
Resolving promises
Rejecting promises
Empty promises
Reacting to promises
Resolution job queues
Using promised data
Error callbacks
Always reacting
Resolving other promises
Promise–like objects
Building callback chains
Promises only change state once
Immutable promises
Many then callbacks, many promises
Passing promises around
Synchronizing several promises
Waiting on promises
Cancelling promises
Promises without executors
Summary
4. Lazy Evaluation with Generators
Call stacks and memory allocation
Bookmarking function contexts
Sequences instead of arrays
Creating generators and yielding values
Generator function syntax
Yielding values
Iterating over generators
Infinite sequences
No end in sight
Alternating sequences
Deferring to other generators
Selecting a strategy
Interweaving generators
Passing data to generators
Reusing generators
Lightweight map/reduce
Coroutines
Creating coroutine functions
Handling DOM events
Handling promised values
Summary
5. Working with Workers
What are workers?
OS threads
Event targets
True parallelism
Types of workers
Dedicated workers
Sub-workers
Shared workers
Worker environments
What's available, what isn't?
Loading scripts
Communicating with workers
Posting messages
Message serialization
Receiving messages from workers
Sharing application state
Sharing memory
Fetching resources
Communicating between pages
Performing sub-tasks with sub-workers
Dividing work into tasks
A word of caution
Error handling in web workers
Error condition checking
Exception handling
Summary
6. Practical Parallelism
Functional programming
Data in, data out
Immutability
Referential transparency and time
Do we need to go parallel?
How big is the data?
Hardware concurrency capabilities
Creating tasks and assigning work
Candidate problems
Embarrassingly parallel
Searching collections
Mapping and reducing
Keeping the DOM responsive
Bottom halves
Translating DOM manipulation
Translating DOM events
Summary
7. Abstracting Concurrency
Writing concurrent code
Hiding the concurrency mechanism
Without concurrency
Worker communication with promises
Helper functions
Extending postMessage()
Synchronizing worker results
Lazy workers
Reducing overhead
Generating values in workers
Lazy worker chains
Using Parallel.js
How it works
Spawning workers
Mapping and reducing
Worker pools
Allocating pools
Scheduling jobs
Summary
8. Evented IO with NodeJS
Single threaded IO
IO is slow
IO events
Multi-threading challenges
More connections, more problems
Deploying to the Internet
The C10K problem
Lightweight event handlers
Evented network IO
Handling HTTP requests
Streaming responses
Proxy network requests
Evented file IO
Reading from files
Writing to files
Streaming reads and writes
Summary
9. Advanced NodeJS Concurrency
Coroutines with Co
Generating promises
Awaiting values
Resolving values
Asynchronous dependencies
Wrapping coroutines
Child Processes
Blocking the event loop
Forking processes
Spawning external processes
Inter-process communication
Process Clusters
Challenges with process management
Abstracting process pools
Server clusters
Proxying requests
Facilitating micro-services
Informed load balancing
Summary
10. Building a Concurrent Application
Getting started
Concurrency first
Retrofitting concurrency
Application types
Requirements
The overall goal
The API
The UI
Building the API
The HTTP server and routing
Co-routines as handlers
The create chat handler
The join chat handler
The load chat handler
The send message handler.
Static handlers
Building the UI
Talking to the API
Implementing the HTML
DOM events and manipulation
Adding an API worker
Additions and improvements
Clustering the API
Cleaning up chats
Asynchronous entry points
Who's typing?
Leaving chats
Polling timeouts
Summary
Index
JavaScript Concurrency
JavaScript Concurrency
Copyright © 2015 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: December 2015
Production reference: 1181215
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham B3 2PB, UK.
ISBN 978-1-78588-923-3
www.packtpub.com
Credits
Author
Adam Boduch
Reviewer
August Marcello III
Commissioning Editor
Edward Gordon
Acquisition Editor
Ruchita Bhansali
Content Development Editor
Divij Kotian
Technical Editor
Gebin George
Copy Editor
Yesha Gangani
Project Coordinator
Nikhil Nair
Proofreader
Safis Editing
Indexer
Tejal Daruwale Soni
Graphics
Jason Monteiro
Production Coordinator
Melwyn Dsa
Cover Work
Melwyn Dsa
About the Author
Adam Boduch has been involved with large-scale JavaScript development for nearly 10 years. Before moving to the front-end, he worked on several large-scale cloud computing products, using Python and Linux. No stranger to complexity, Adam has practical experience with real-world software systems, and the scaling challenges they pose. He is the author of several JavaScript books, including JavaScript at Scale, Packt Publishing, and is passionate about innovative user experiences and high performance.
About the Reviewer
August Marcello III is a highly passionate software engineer with nearly two decades of experience in the design, implementation, and deployment of modern client-side web application architectures in enterprise. An exclusive focus on delivering compelling SaaS-based User Experiences throughout the Web ecosystem has proven to be rewarding both personally and professionally. His passion for emerging technologies in general, combined with a particular focus on forward-thinking JavaScript platforms, have been a primary driver in his pursuit of technical excellence. When he's not coding, he can be found trail running, mountain biking, and spending time with his family and friends.
Many thanks to Chuck, Mark, Eric, and Adam, who I have had the privilege to work with and learn from. With gratitude to my family, friends, and the experiences I have been blessed to be a part of.
www.PacktPub.com
Support files, eBooks, discount offers, and more
For support files and downloads related to your book, please visit www.PacktPub.com.
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
Support files, eBooks, discount offers, and morehttps://www2.packtpub.com/books/subscription/packtlib
Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book library. Here, you can search, access, and readPackt's entire library of books.
Why subscribe?
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Free access for Packt account holders
If you have an account with Packt at www.PacktPub.com, you can use this to access PacktLib today and view 9 entirely free books. Simply use your login credentials for immediate access.
For Melissa, Jason, and Simon, thanks for all your love and support.
Preface
It wasn't long ago when I would dread using many of the web applications I had come to depend on. When they worked, they were fantastic; when they didn't, it was a nightmare. Especially frustrating was the clear fact that there weren't any bugs in the JavaScript code driving the application. No, the problem was that often there was too much code running, perhaps because it was processing a large data set. The end result was always the same: the UI would freeze, and I would helplessly curse the Web.
Nowadays, this doesn't happen as frequently. We've fixed many of the common JavaScript problems from years ago. Something that hasn't caught on as fast as I had hoped is concurrency in JavaScript. There are little bits of concurrency sprinkled all throughout our applications, but seldom do we see truly concurrent JavaScript code.
Let's change the status quo.
What this book covers
Chapter 1, Why JavaScript Concurrency?, is an introduction to concurrency in JavaScript.
Chapter 2, The JavaScript Execution Model, takes you through the mechanisms that run our JavaScript code.
Chapter 3, Synchronizing with Promises, looks at synchronization techniques using promises.
Chapter 4, Lazy Evaluation with Generators, will get your grips to conserving resources by computing lazily.
Chapter 5, Working with Workers, looks at achieving true parallelism in JavaScript.
Chapter 6, Practical Parallelism, will help you in identifying the right parallelization problems to solve.
Chapter 7, Abstracting Concurrency, will get your hands dirty writing concurrent code that reads like regular code.
Chapter 8, Evented IO with NodeJS, will show you how concurrency semantics work in this environment.
Chapter 9, Advanced NodeJS Concurrency, is learning about specific Node concurrency issues.
Chapter 10, Building a Concurrent Application, is all about putting it all together.
What you need for this book
Requirements for this book are as follows:
A recent version of any major browser
NodeJS (at least 4.0)
A code editor
Who this book is for
JavaScript Concurrency is written for any JavaScript developer who wants to learn how to write more efficient, powerful, and maintainable applications that utilize the latest developments in the JavaScript language.
All aspects of concurrent, asynchronous, and parallel programming are covered from first principles, and by the end of the book you'll be able to create a fully-worked application that leverages all the topics covered in the book.
Conventions
In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.
Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: We can include other contexts through the use of the include directive.
A block of code is set as follows:
// Loads the worker script, and starts the
// worker thread.
var worker = new Worker('worker.js');
New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: Clicking the Next button moves you to the next screen.
Note
Warnings or important notes appear in a box like this.
Tip
Tips and tricks appear like this.
Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of.
To send us general feedback, simply e-mail <[email protected]>, and mention the book's title in the subject of your message.
If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
Downloading the example code
You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
Errata
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at <[email protected]> with a link to the suspected pirated material.
We appreciate your help in protecting our authors and our ability to bring you valuable content.
Questions
If you have a problem with any aspect of this book, you can contact us at <[email protected]>, and we will do our best to address the problem.
Chapter 1. Why JavaScript Concurrency?
JavaScript is not a language associated with concurrency. In fact, it's frequently associated with the exact opposite—concurrency challenges. This has changed a lot over the past few years, especially with new language features in ES 2015. Promises have been used in JavaScript for many years; only now, they're a native type. Generators are another addition to the language that changes the way we think about concurrency in JavaScript. Web workers have been in browsers for several years, and yet, we don't see them used that often. Perhaps, it has less to do with workers and more about our understanding of the role that concurrency plays in our applications.
The aim of this chapter is to explore some general concurrency ideas, starting with what, exactly, concurrency is. If you don't have any sort of concurrent programming in your background, it's fine because this chapter is a perfect starting point for you. If you've done concurrent programming in the past using JavaScript or some other language, think of this chapter as a refresher, only with JavaScript as the context.
We'll wrap up this chapter with some overarching concurrency principles. These are valuable programming tools that we should keep in the back of our heads while writing concurrent code. Once we have learned to apply these principles, they'll tell us whether we're on the right track with our concurrency design, or that we need to take a step back and ask ourselves what we're really trying to achieve. These principles take a top-down approach to the design of our application. This means that they're applicable from the very start, even before we've started writing any code. Throughout the book, we'll be referring to these principles, so if you only read one section in this chapter, make sure it's Concurrency principles at the end.
Synchronous JavaScript
Before we start conjuring large-scale concurrent JavaScript architectures, let's shift our attention to the good old synchronous JavaScript code that we're all familiar with. These are the blocks of JavaScript code that are called as the result of a click event, or run as the result of loading a webpage. Once they start, they don't stop. That is to say, they're run-to-completion. We'll dig into run-to-completion a little more in the following chapter.
Note
We'll occasionally see the term synchronous and serial used interchangeably throughout the chapters. They're both referring to code statements that run one after another until there's nothing more to run.
Despite JavaScript being designed as a single-threaded, run-to-completion environment, the nature of the web complicates this. Think about the web browser, and all it's moving parts. There's the Document Object Model (DOM) for rendering user interfaces and XMLHttpRequest (XHR) objects for fetching remote data sources, to name a couple. Let's take a look at the synchronous nature of JavaScript and the asynchronous nature of the web.
Synchronicity is easy to understand
When code is synchronous, it's easier to understand. It's easier to mentally map the instructions that we're seeing on the screen to sequential steps in our heads; do this, then do that; check this, if true, do that, and so on. This type of serial processing is easy enough to understand, because there aren't any surprises, assuming the code isn't completely horrible. Here's an example of how we might visualize a chunk of synchronous code:
Synchronicity is easy to understandConcurrent programming, on the other hand, isn't so easy to grasp. This is because there's no linear logic for us to follow in our code editors. Instead, we constantly jump around, trying to map what this piece of code is doing relative to that piece of code. Time is an important factor with concurrent designs; it is something that goes against the brain's natural way of comprehending code. When we read code, we naturally execute it in our heads. This is how we figure out what it's doing. This approach falls apart when the actual execution doesn't line up with what's in our head. Normally, code reads like a book—concurrent code is like a book where the pages are numbered, but out of order. Let's take a look at some trivial pseudo JavaScript code:
var collection = [ 'a', 'b', 'c', 'd' ];
var results = [];
for (let item of collection) {
results.push(String.fromCharCode(item.charCodeAt(0)));
}
// [ 'b', 'c', 'd', 'e' ]
In traditional multi-threading environments, a thread is something that runs asynchronously with other threads. We use threads to take advantage of multiple CPUs found on most systems today, resulting in better performance. However, this comes at a cost because it forces us to rethink how our code is executed at runtime. It's no longer the usual step by step execution. This code could be running alongside other code in another CPU, or it could be competing with other threads for time on the same CPU.
A lot of simplicity goes away when we introduce concurrency to synchronous code—it's the code equivalent of brain freeze. This is why we write concurrent code: code that makes an upfront assumption of concurrency. We'll elaborate on this concept as we progress through the book. With JavaScript, it's important to assume a concurrent design, because that's the way the web works.
Asynchronous is inevitable
The reason that concurrency in JavaScript is such an important idea is because the web is a concurrent place, both from a very high level and an implementation detail level. In other words, the web is concurrent because at any given point in time, there's oodles of data flowing over the miles of fiber, which encase the globe. It has to do with the applications themselves that are deployed to web browsers, and how the back-end servers handle the litany of requests for data.
Asynchronous browsers
Let's take a closer look at the browser and the kinds of asynchronous actions found there. When a user loads a webpage, one of the first actions that the page will perform is to download and evaluate our JavaScript code that goes with the page. This in itself is an asynchronous action, because while our code downloads, the browser will continue doing other things, such as rendering page elements.
Another asynchronous data source that arrives over the network is the application data itself. Once our page has loaded and our JavaScript code starts running, we'll need to display some data for the user. This is actually one of the first things that our code will do so that the user has something to look at right away. Again, while we're waiting on this data to arrive, the JavaScript engine will move our code right along to it's next set of instructions. Here's a request for remote data that doesn't wait for the response before continuing on with executing code:
Asynchronous browsersAfter the page elements have all been rendered and populated with data, the user starts interacting with our page. This means events are dispatched—clicking an element dispatches a click event. The DOM environment, where these events are dispatched from, is a sand-boxed environment. This means that within the browser, the DOM is a subsystem, separate from the JavaScript interpreter, which runs our code. This separation makes certain JavaScript concurrency scenarios especially difficult. We'll cover these in depth in the next chapter.
With all these sources of asynchronicity, it's no wonder that our pages can become bloated with special case handling to deal with the edge cases that inevitably pop up. Thinking asynchronously isn't natural, so this type of monkey-patching is the likely result of thinking synchronously. It's best to embrace the asynchronous nature of the web. After all, a synchronous web can lead to unbearable user experiences. Now, let's dig a little further into the types of concurrency we're likely to face in our JavaScript architectures.
Types of concurrency
JavaScript is a run-to-completion language. There's no getting around it, despite any concurrency mechanisms that are thrown on top of it. In other words, our JavaScript code isn't going to yield control to another thread in the middle of an if statement. The reason this matters is so that we can pick a level of abstraction that makes sense in helping us think about JavaScript concurrency. Let's look at the two types of concurrent actions found in our JavaScript code.
Asynchronous actions
A defining characteristic of asynchronous actions is that they do not block other actions that follow. Asynchronous actions don't necessarily mean fire-and-forget. Rather, when the part of the action we're waiting on completes, we run a callback function. This callback function falls out of sync with the rest of our code; hence, the term asynchronous.
In web front-ends, this generally means fetching data from a remote service. These fetching actions are relatively slow, because they have to traverse the network connection. It makes sense for these actions to be asynchronous, just because our code is waiting on some data to return so that it can fire a callback function, doesn't mean the user should have to sit around and wait too. Furthermore, it's unlikely that any screen that the user is currently looking at depends on only one remote resource. So, serially processing multiple remote fetch requests would have a detrimental effect on the user experience.
Here's a general idea of what asynchronous code looks like:
var request = fetch('/foo');
request.addEventListener((response) => {
// Do something with response
now that it has arrived.
});
// Don't wait with the response, update the DOM immediately.
updateUI();
Tip
Downloading the example code
You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
We're not limited to fetching remote data, as the single source of asynchronous actions. When we make network requests, these asynchronous