Reputation: 62712
I have this simple nodejs application, which generates dummy date for my web application. All it does is:
Of course, all the actions are asynchronous and I want to execute them sequentially, one after another. For me, it was simpler to write something to manage this kind of the flow, however, I would like a mainstream solution, which would support other kinds of flows. For instance, running in parallel and stopping all on the first failure.
For your reference, please, find below the skeleton, depicting my solution:
/*global require, console, process*/
var mongo, db, inventory, createChain;
function generateInventory(count) {
// returns the generated inventory
}
function generateInvoices(count, inventory) {
// returns the generated invoices
}
function generateConst() {
// returns the generated const data
}
mongo = require('mongojs');
db = mongo.connect('dummy', ['invoices', 'const', 'inventory']);
createChain = function () {
"use strict";
var chain = [false], i = 0;
return {
add: function (action, errMsg, resultCallback) {
chain[chain.length - 1] = {action: action, errMsg: errMsg, resultCallback: resultCallback};
chain.push(false);
return this;
},
invoke: function (exit) {
var str, that = this;
if (chain[i]) {
chain[i].action(function (err, o) {
if (err || !o) {
str = chain[i].errMsg;
if (err && err.message) {
str = str + ": " + err.message;
}
console.log(str);
} else {
if (chain[i].resultCallback) {
chain[i].resultCallback(o);
}
i += 1;
that.invoke(exit);
}
});
} else {
console.log("done.");
if (exit) {
process.exit();
}
}
}
};
};
createChain()
.add(function (callback) {
"use strict";
console.log("Dropping the dummy database.");
db.dropDatabase(callback);
}, "Failed to drop the dummy database")
.add(function (callback) {
"use strict";
console.log("Populating the inventory.");
db.inventory.insert(generateInventory(100), callback);
}, "Failed to populate the inventory collection", function (res) {
"use strict";
inventory = res;
})
.add(function (callback) {
"use strict";
console.log("Populating the invoices.");
db.invoices.insert(generateInvoices(10, inventory), callback);
}, "Failed to populate the invoices collection")
.add(function (callback) {
"use strict";
console.log("Populating the const.");
db["const"].insert(generateConst(), callback);
}, "Failed to populate the const collection")
.invoke(true);
Can anyone suggest a relevant nodejs package, which would also be easy to use?
Thank you very much.
Upvotes: 0
Views: 387
Reputation: 973
Actually, for sequential flow control, you should use waterfall
As an example:
async.waterfall([
function(cb){
cb(null,1);
},
function(r,cb){
// r=1
cb(null,2)
},
function(r,cb){
// r=2
cb(null,3)
}
],function(e,r){
// e=null
// r=3
})
This will execute sequentially. If you callback an error early, (i.e. cb("error")), then it will directly go to the final function(e,r), with e="error" and r=undefined Notice how function(r,cb){} can become precomposed in a util library to handle commonly reused blocks and make things in the future easier.
Upvotes: 0