Как практический пример кода должен быть структурой, чтобы избежать ада обратного вызова?

Я страдал от ада обратного вызова в моем коде 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 ответ

Решение

Я просто отформатировал его и удалил 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();
}

Если вы начнете делать больше вложенных вещей, вы можете использовать асинхронные функции *, такие как "водопад", "серия", "параллель" и т.д.

Другие вопросы по тегам