See article on the pitfalls of boilerplate, and how each copy brings new errors, by Kristofer Selbekk.

Your Javascript app runs any number of async tasks, reacting to their outcome. You diligently manage the lifecycle of your tasks, but ask yourself, is that just more boilerplate? Have you considered all the edge cases, or did you miss something this time around?

A Task Wrapper that’s React-able, Cancellable, Time Bounded, & Restartable. Click here for a live demo.

In this article, we’ll look at a JavaScript Task Wapper for arbitrary work, that can be reacted to, and is cancellable, time bounded, and restartable.

We’ll wrap it in a Vue mixin and put it to use in a single page Vue app that fetches images from Flickr, reacting to all of it’s lifecycle states.

The Task Wrapper

A task wrapper isn’t rocket science. Here’s what a typical wrapper lifecycle looks like:

FIgure 1: Task — Basic Lifecycle

The task is idle when created. Invoking start(request) kicks of the encapsulated work and the task is running. When the work completes successfully, it calls done(response) to notify the task. The task has succeeded. If the work fails, it calls error(reason) to notify the task. The task has failed. A running task can be cancelled at any time by calling cancel(reason) . The task is cancelled. Optionally, the task can start a timer to monitor the running time of a running task and stop the task if the timer fires. The task is in timeout. The task can be reset at any time which clears the task’s data and sends it back to idle. If it’s running, the task is first cancelled. The task can now be restarted (Step 1).

Asideⁿ: Under the hood, our Task class is, first and foremost, a Deterministic Finite Automaton (DFA). We’re going to give it memory (tape for you CS geeks) so we’re really a Turing Machine. Unlike ANSI C/C++, the JavaScript language does not place a limit on the available memory (vs. physical limits and interpreter realities). That makes us Turing Complete!

A Deeper Dive

Employing a DFA in the Task class gets us a bulk of our requirements — transitioning between states (or staying in a current state) based on user inputs and notifications from the encapsulated work.

We will need to augment the DFA with code, e.g. to initialize data in the idle state and start a timer when running, and provide it with memory to manage the request to, and the result from, the encapsulated work.

Since we’re allowing the Task to be restartable (after reset), we will need to guard against stale notifications of completion or errors, from earlier previously cancelled but unterminated work. We’ll create a unique session identifier when entering the idle state and require work notifications to include the session id.

Design Note: We’re deliberately skipping a cancel/cancelDone dance because our use cases can’t wait for cancel to complete, e.g. when resetting while running, we want to immediately start the next session when a user cancels a current search and starts a new one.

Figure 2 show shows our DFA state diagram augmented with the code and decision blocks.