Introduction
TaskGroup provides two classes, Task and TaskGroup
Tasks
Tasks are used to wrap a function (both synchronous and asynchronous functions are supported) inside a task execution flow.
This is useful as a consistent interface for executing tasks and doing something on their completion or failure, as well as catching uncaught errors and handling them safely.
We can define a synchronous task like so:
var Task = require('taskgroup').Task
// Create a task for our synchronous function
var task = new Task(function () {
// Do something ...
return "a synchronous result"
// You can also return an error
// return new Error("something went wrong")
})
// Add our completion callback for once the task has completed
task.done(function (err, result) {
// Do something now that the task has completed ...
console.log([err, result])
/* [null, "a sychronous result"] */
})
// Execute the task
task.run()And an asynchronous task like so:
TaskGroup
Often at times, we want to execute multiple things and wait for the completion. TaskGroup makes this easy with the other class, TaskGroup.
We simply create a TaskGroup and add our Tasks to it!
The
storeResultconfiguration property is new to TaskGroup v5. By default, TaskGroup v5 does not store results, whereas TaskGroup v4 did. WithoutstoreResult: truetheresultsparameter on thedonecompletion callback would be undefined. In the examples here we wish to store the results such that the order execution becomes obvious, normally you may or may not want to usestoreResult.
Now by default, the TaskGroup will execute serially. This means that each task will execute one by one, waiting for the previous task to complete before moving on to the next task. This can also be considered having a concurrency of 1. This is called serial execution.
If we wanted to execute say two tasks at a time we could want a concurrency of 2, or three tasks at a time, a concurrency of 3 would be set, or unlimited tasks at a time, a concurrency of 0 would be set.
We can customise the concurrency of the task group by passing it over as a configuration option, either via the TaskGroup constructor or via the setConfig method. Let's see what this would look like if we were do a concurrency of 0. This is called parallel execution.
Notice how the groups results are now in a different order. This occured because with parallel execution, we didn't have to wait for the asynchronous function to complete its 5 second delay before executing and completing the second function (the synchronous one).
You can mix and match as many functions as you want with TaskGroups.
Nested TaskGroups
You can also nest TaskGroups inside TaskGroups.
A common use case for this is when you would like a portion of your tasks to execute in parallel, and portion of your tasks to execute in serial.
Such a use case would look like so:
Handling Errors
Safely handling errors is an important thing to do. TaskGroup makes this easy by safely catching any errors that your task may throw, isolating the destruction to the task alone, and providing to the task or taskgroup's completion callback.
When an error is detected, the remaining tasks in a TaskGroup will be cleared, and the TaskGroup's completion callback with the error will be fired. If you wish to not abort on error, you can set abortOnError: false. More configuration options.
Which comes in very handy when dealing with asynchronous parallel code:
Now even though the first task's completion callback still fires, it is successfully ignored, as the TaskGroup has exited.
Notes
Promise Style Mistakes
A common mistake for people coming from the complex land of promises, is that they may make code like this:
Expecting the completion callback to fire right away. However, as the TaskGroup is just an event emitter, the completion listener is only fired at the point in time when the complete event is emitted. As such, you should always add your completion listener before you run your task or taskgroup, never after.
Legacy Environments
In Node v0.8 and browser environments, TaskGroup may not be able to catch all thrown errors due to the lack of usable domains in those environments (domains only became usable in Node v0.10.0 and above).
To help ensure errors are caught in all environments, be sure to always follow the best practices for error handling, regardless of your environment.
Graduation
Now you know all the essentials to getting started with coding the most amazing (a)synchronous parallel/serial code in your life. Enjoy!
Last updated
Was this helpful?