Writing Async Programs in JavaScript
Preface
There is no doubt that JavaScript, despite its history, has become to be one of the most popular programming languages today. JavaScript, due to its asynchronous nature, can present some challenges for those who are new to the language. In this article, we are going to write small async programs using promises and async/await. Using these examples, we are going to identify some simple patterns that you can use for your own programs.
If you are new to JavaScript, you may want to first check out my other article before reading this one.
All the code examples in this article are written for the Node environment. If you don’t have Node installed, you can see the Appendix 1 for instructions. Even though all the programs are written for Node, you can apply the same principles for scripts running in the browser. Also, all the code examples for this article are available on Gitlab.
Introduction
Whether or not people believe that JavaScript is a real programming language, the reality is that it’s not going to go anywhere anytime soon. If you are a web developer you might as well spend some time and learn its good and bad parts.
JavaScript is single-threaded and favors non-blocking asynchronous flows. If you are new to the language, it can become really frustrating when things don’t work the way you expect them to. Asynchronous programming demands more patience and a different kind of thinking that’s different from synchronous programming.
In the synchronous model everything happens in a sequence one at a time. Because of that it’s easier to reason about programs. But in the asynchronous model, operations can start or finish in any order at any point in time. Because of that simply relying on a sequence is not sufficient. Asynchronous programming demands more thought in terms of program flow and design.
In this article, we are going to explore a couple of short async programs. We are going to start with simple programs and work our way up to more complex ones. Below is an overview of the scripts that we are going to be writing:
- A script that writes the content of a file to another file.
- A script that writes the contents of multiple files to new files.
- A script that parses and formats CSV files in a directory and outputs new CSV files to another folder.
Promises and Async/await
Let’s take a moment and quickly review the basics of promises and async/await.
Promises
- A promise is an object that represents the result of an asynchronous operation.
- A promise is either resolved with a “success” value or rejected with a “failure” value.
- Generally speaking, resolved values are accessed with a callback’s argument to a
then
block. And the rejected values are access with a callback's argument to acatch
block. - In modern JavaScript environments, you can access a promise constructor through the global object as
Promise
. - A promise can be created using the
Promise
constructor using thenew
keyword. That is: const p = new Promise((r, j) => {});
- The
r
callback is used to resolve the promise with a value and thej
callback is used to reject the promise. - The
Promise
constructor has some useful static methods likeall
,race
,resolve
, andreject
. Theall
method accepts an array of promises and will attempt to resolve all of them concurrently and return a promise that resolves to an array with the resolved values. Therace
methods takes an array of promises and resolves or rejects the first promise that finishes. Theresolve
method creates a promise and resolves it to the given value. Thereject
method creates a promise and rejects it with the given value.
Async/await
- The purpose of async/await functions is to simplify the behavior of using promises synchronously and to perform some behavior on a group of Promises. From MDN
- Just as Promises are similar to structured callbacks, async/await is similar to combining generators and promises. From MDN
- A function can be marked as an asynchronous function with the
async
keyword. That is:async function hello() {}
orconst hello = async() => {};
. - An
async
function always returns a promise. If a value is returned from anasync
function, it will be implicitly wrapped in a promise. - If there is an uncaught exception thrown inside an
async
function, the promise returned is rejected with the exception. - The
await
operator can be used inside anasync
function before statements that return a promise. In that case, the execution of the function is "paused" until the promise is resolved or rejected. - The
await
operator is only valid inside anasync
function.
You can read the rest of the article on medium.com