statemachinenodejs
v1.0.1
Published
Super simple utility to serialize an operation that uses multiple IO callbacks
Downloads
9
Readme
StateMachineNodeJS
A simple utility to serialize an operation that uses multiple IO callbacks. People who've used this suggested I make this publicly avilable. So here it is. Sorry the documentation sucks. I hope the sample gets the point across and shows you how to use it.
npm install statemachinenodejs
The problem
When writing a function in NodeJS that needs to make multiple IO calls in stages, oftentimes they are chained. As more IO calls are needed the chain gets long and complicated.
function concatFiles(fileAPath, fileBPath, outputPath, completionFn)
{
var fileAContents = '';
var fileBContents = '';
var errorCount = 0;
fs.readFile(fileAPath, 'utf8', nextFn(states.concat,
function(err, data)
{
if(err) {
completionFn(err);
}
else {
fileAContents = data;
fs.readFile(fileBPath, 'utf8', nextFn(states.concat,
function(err, data)
{
if(err) {
completionFn(err);
}
else {
fileBContents = data;
fs.writeFile(outputPath, fileAContents + fileBContents,
function(err)
{
completionFn(err);
}
);
}
}
);
}
}
);
}
My solution
With StateMachineNodeJS you can organize it more like a regular step-by-step function and run operations in parallel when possible.
function concatFiles(fileAPath, fileBPath, outputPath, completionFn)
{
var fileAContents = '';
var fileBContents = '';
var errorCount = 0;
StateMachine.go(this, function(nextFn)
{
// Create the object that holds the state functions
var states = {
// Must have a 'start' state. All other state names are arbitrary
start:
function()
{
// Start the io operation providing the callback nextFn provided above by the state machine.
// In this case anoter callback is provided to handle the IO completion. This callback
// will always be called before the next state function is called
fs.readFile(fileAPath, 'utf8', nextFn(states.concat,
function(err, data)
{
if(err) {
errorCount++;
}
else {
fileAContents = data;
}
}
));
fs.readFile(fileBPath, 'utf8', nextFn(states.concat,
function(err, data)
{
if(err) {
errorCount++;
}
else {
fileBContents = data;
}
}
));
},
concat:
function()
{
if(errorCount){
nextFn(states.complete)('error');
}
// In this case we don't care about handling the IO callback
// function, we just want to move to the next state
fs.writeFile(outputPath, fileAContents + fileBContents, nextFn(states.complete));
},
complete:
function(err)
{
completionFn(err);
}
};
// Returns states object
return(states);
});
}