Reputation: 29
I've been suffering from callback hell in my JavaScript code and I believe this is caused by my previous experience in mainly purely synchronous/threaded Java code.
I learn well by example but have, as of yet, been unable to find a good "before and after" example of callback hell solved in many of the situations I find it occurring in.
I would appreciate it if some kind soul could show me what the code as provided below should be structure so as to avoid callback hell (using libraries such as async if necessary), as I believe a practical example would benefit me and others reading the question.
Wrangling with this for a while, I still could not figure out a way of it working well that would allow a call on the original callback as well as retaining the logic of the code.
Any help if well appreciated, thank you for your time. :)
Code: var fs = require('fs'); var zlib = require('zlib');
var defaultOptions = require('./options/defaults');
function FeatherDB (sourcePath, options)
{
if (options === undefined)
{
// use defaults if options not provided
options = defaultOptions;
}
else
{
// ensure all keys are supplied
for (key in defaultOptions)
{
if (options[key] === undefined)
{
options[key] = defaultOptions[key];
}
}
}
this.sourcePath = sourcePath;
this.options = options;
}
FeatherDB.prototype.load = function (callback)
{
var thiz = this;
fs.exists(this.sourcePath, function (error, doesExist) {
if (error)
{
callback(error);
return;
}
if (doesExist)
{
fs.readFile(thiz.sourcePath, function (error, rawFileData) {
if (error)
{
callback(error);
return;
}
if (thiz.options.compress)
{
zlib.gunzip(rawFileData, function (error, rawUncompressedData) {
if (error)
{
callback(error);
return;
}
try
{
thiz.documents = JSON.parse(rawUncompressedData.toString('utf8'));
}
catch (error)
{
callback(error);
return;
}
callback(null);
})
}
else
{
try
{
thiz.documents = JSON.parse(rawFileData.toString('utf8'));
}
catch (error)
{
callback(error);
return;
}
callback(null);
}
})
}
else
{
thiz.documents = {};
callback(null);
}
})
}
Upvotes: 1
Views: 163
Reputation: 13532
I justed formatted it and removed the fs.exists
check. If the file doesn't exist readFile will fail and send an error back.
FeatherDB.prototype.load = function (callback) {
var thiz = this;
fs.readFile(thiz.sourcePath, function (error, rawFileData) {
if (error) {
thiz.documents = {};
return callback(error);
}
if (!thiz.options.compress) {
FeatherDB.parse(rawFileData.toString('utf-8'), callback);
return;
}
zlib.gunzip(rawFileData, function (error, rawUncompressedData) {
if (error) {
return callback(error);
}
FeatherDB.parse(rawUncompressedData.toString('utf-8'), callback);
});
});
}
FeatherDB.prototype.parse(data, callback) {
try {
thiz.documents = JSON.parse(data);
} catch (error) {
return callback(error);
}
callback();
}
If you start doing more nested stuff you can look into using async.* functions like waterfall, series, parallel etc.
Upvotes: 1