一个实用的代码示例应该如何构建以避免回调地狱?

时间:2014-06-29 00:50:25

标签: node.js callback asynccallback

我在JavaScript代码中遇到了回调地狱,我相信这是我之前在主要纯粹的同步/线程Java代码方面的经验造成的。

我通过榜样学到了很多东西,但到目前为止,还没有找到一个好的"之前和之后"在我发现它发生的许多情况下,回调地狱的例子已经解决了。

如果某种灵魂可以告诉我下面提供的代码应该是什么结构以避免回调地狱(如果必要的话使用async这样的库),我将不胜感激,因为我相信一个实际的例子会使我和其他人受益读这个问题。

对此问题进行了一段时间的讨论,我仍然无法找到一种运行良好的方法,可以调用原始回调并保留代码的逻辑。

任何帮助,如果非常感谢,谢谢你的时间。 :)

代码:     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);
        }
    })
}

1 个答案:

答案 0 :(得分:1)

我justed格式化了它并删除了fs.exists检查。如果文件不存在,readFile将失败并返回错误。

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();
}

如果你开始做更多嵌套的东西,你可以考虑使用async。*函数,如瀑布,系列,并行等。