Jobify
RequireJS like asynchronous task runner with task dependencies.
Install
npm install jobify --save
Usage
var Jobify = require('jobify');
A very basic use case.
Jobify()
.task('foo', function(task)
{
task.resolve('World');
})
.task('bar', ['foo'], function(task, foo)
{
if (foo === 'World') {
task.resolve('Hello ' + foo + '!');
} else {
task.reject('Expected World');
}
})
.done(function(err, values)
{
if (err instanceof Error) {
console.error(err.message);
} else {
console.log(values.bar);
}
});
Starting The Job
None of the tasks are run until done is called. Done does not execute the tasks
immediately though. It is guaranteed to be asynchronous. Because it is
asynchronous, you can also call .done()
first and then synchronously add
tasks.
Return Value
A task callback doesn't have to be asynchronous. You can return a task value
instead of calling task.resolve()
.
Jobify()
.task('foo', function(task)
{
return 'World';
})
.task('bar', ['foo'], function(task, foo)
{
return 'Hello ' + foo + '!';
})
.done(function(err, values)
{
console.log(values.bar);
});
Duplicate Names
You can define multiple tasks with the same name. The task is not considered
resolved until all of the callbacks are resolved. The resolved task value will
be an array of all resolution values, in the order of callback registration.
Jobify()
.task('foo', function(task)
{
setTimeout(function()
{
task.resolve('Hello');
}, 1000);
})
.task('foo', function(task)
{
setTimeout(function()
{
task.resolve('World!');
}, 500);
})
.done(function(err, values)
{
console.log(values.foo.join(" "));
});
Errors
If you throw an error or call task.reject()
, then the job stops immediately
and no further tasks will be run. Any task that is running in parallel with a
rejected task will finish, but its resolution/rejection will be ignored.
Anything thrown or passed to task.reject()
will be normalized to an Error
instance. A non-Error
value will be used as the error message of a newly
constructed Error
instance.
Jobify()
.task('foo-parallel', function(task)
{
setTimeout(function()
{
task.resolve('... this value will be ignored');
}, 0);
})
.task('foo', function(task)
{
task.reject("Oh no!");
})
.task('bar', ['foo'], function(task, foo)
{
})
.done(function(err, values)
{
if (err instanceof Error) {
console.log(err.message);
}
});
Throwing an exception synchronously is the same as calling task.reject()
.
Jobify()
.task('foo', function(task)
{
throw new Error("Oh no!");
})
.task('bar', ['foo'], function(task, foo)
{
})
.done(function(err, values)
{
if (err instanceof Error) {
console.log(err.message);
}
});
API
Class Jobify
Jobify()
new Jobify()
Constructs a new Jobify
instance.
.task(name, taskCallback)
.task(name, dependencies, taskCallback)
name
is required and must be a string.dependencies
is an optional array of task names.taskCallback
is required and must be a function.- returns the
Jobify
instance for method chaining.
Runs taskCallback
when all dependencies
have been met.
taskCallback(task, ...)
task
is a Task
instance....
is zero or more arguments of any type.
Resolved task values matching the task's dependencies will be passed in order
starting after the task
argument.
.done()
.done(doneCallback)
doneCallback
is an optional function to be called when all tasks have been
resolved or if a task is rejected.- returns the
Jobify
instance for method chaining.
Begins running tasks. No tasks are run until .done()
has been called at least
once.
doneCallback(err, values)
err
an Error
instance or null
.values
an object.
The err
argument will either be an Error
instance if any tasks were
rejected, or null
.
The values
argument is a map of all resolved task values.
.copy()
- returns a new
Jobify
instance.
Create's a copy of the Jobify
instance which defines the same tasks as the
source instance.
This method must be called before calling .done()
.getFactory()
Create's a function which returns a new copy of the source instance each time
it's called.
This method must be called before calling .done()
.getStatus()
Possible Return Values:
- "ready"
.done()
has not been called. - "running"
.done()
has been called, no tasks have been rejected, but not all
tasks have been resolved either. - "closed" All tasks have been resolved or a task was rejected.
Class Task
The first argument passed to all taskCallback
functions is an instance of this
class.
.resolve(value)
value
an optional value of any type.
Call this method to resolve the task. The value will be passed to any dependent
tasks.
Calling this method more than once or after calling .reject()
, has no effect.
.reject(err)
err
an optional Error
instance or string.
Call this method to reject the task. The err will be passed to all
doneCallbacks
as the first argument. If a string is given for err
, a new
Error
instance will be constructed using the string as the error message.
Calling this method more than once or after calling .resolve()
has no effect.
.isClosed()
Returns true
if either .resolve()
or .reject()
have been called. Returns
false
otherwise.
.index
An integer value greater than or equal to zero.
If more than one task with the same name is added to job, this number indicates
the order in which the currently running task was added.
.job
A Jobify
instance.
This is the instance that the task was added to.