Callback Hell Converted To Promises In Modules & Passing Data

Callback Hell Converted To Promises In Modules & Passing Data

I wanted to log my take on callback hell as I couldn’t really find much information on how to pass data through your callback chain after being changed to promises, it turns out it is pretty easy when you know how and the results are great crazy looking code looks very nice.

I do a lot of data analysis with ffmpeg, ffprobe and I want to give a useful example of how to do this but using promises.

I also want to have my functions in a helper file so they are separate and not all bundled in one file.

We are going to select a media file and grab analyis its data using ffprobe then we will simply read the file using Node fs filesystem.

New Promise Code

Here is the final code.

index.js

var fs = require('fs');

const pro = require('./helpers');

var data = {
    file: '/Users/picca/Desktop/out.mp4'
};

const fileData = () => {

    return pro.probe(data)
    .then(data => pro.read(data));

}; 

fileData().then(function(res) {

    console.log('res', res);

}).catch(function(err) {

    console.log(err);

});

And here is the helper.js

var fs = require('fs');

const probe = (data) => {

    return new Promise((resolve, reject) => {

        require('child_process').execFile('/usr/local/bin/ffprobe', [
            '-show_format',
            '-show_streams',
            '-select_streams',
            'a',
            '-of',
            'json',
            '-loglevel',
            'error',
            data.file
        ], (err, stdout, stderr) => {

            if (err) return reject(err);
            
            data.probe_data = JSON.parse(stdout);
            
            resolve(data);


        });

    });

};

const read = (data) => {

    return new Promise((resolve, reject) => {
    
        fs.readFile(data.file, {}, (err, res) => {

            if (err) return reject(err)
            
            data.read_data = res;
            
            resolve(data)
        
        });
    
    });

}

exports.probe = probe;
exports.read = read;

We are passing the main file through the chain and adding to the data array as it goes then we will get a full result within our then function.

Previous Code

This was the previous code.

var fs = require('fs');

function probe(data, callback) {

    require('child_process').execFile('/usr/local/bin/ffprobe', [
        '-show_format',
        '-show_streams',
        '-select_streams',
        'a',
        '-of',
        'json',
        '-loglevel',
        'error',
        data.file
    ], (err, stdout, stderr) => {

        if (err) {

            callback({
                error: true,
                message: err
            });

        } else {

            data.probe_data = JSON.parse(stdout);

            callback({
                error: false,
                message: err
            });

        }

    });

}

function read(data, callback) {

    fs.readFile(data.file, {}, (err, res) => {

        if (err) {

            callback({
                error: true,
                message: err
            });

        } else {

            data.read_data = res;

            callback({
                error: false,
                message: err
            });

        }

    });

}


var data = {
    file: '/Users/picca/Desktop/out.mp4'
};

probe(data, function(res) {

    read(res, function(res) {

        console.log(res);

    });

});

At first glance it might not seem that different but we are only chaining two functions together here with multiple callbacks of five or more you really start to see the improvement.

Leave a comment

Your email address will not be published. Required fields are marked *