JSFiddle - React, Tailwind, and code Playground

JavaScript

function encadear() {
    var cadeia = [].slice.call(arguments);
    return function(dadoInicial, end) {
	var fns = cadeia.slice();
        function exec(err, data) {
            if (err) return end(err);
            var next = fns.pop();
            if (!next) return end(null, data);
            next(data, exec);
        }
        exec(null, dadoInicial);
    }
}

function add1(n, callback) {
    setTimeout(function() {
        callback(null, n + 1);
    }, 10);
}

function mul3(n, callback) {
    setTimeout(function() {
        callback(null, n * 3);
    }, 10);
}
var add1mul3 = encadear(mul3, add1);

/* ---- */

var stack = [
    function(done) {
        add1mul3(4, done);
    },
    function(done) {
        add1mul3(3, done);
    }
];

function runStack(arr, done) {
    var callbacks = 0,
        total = arr.length,
        res = [];

    for (var i = 0; i < total; i++) {
        (function(index, fn) { // cria um escopo próprio
            fn(function(err, val) {
                if (err) console.log(err);
                res[index] = val;
                callbacks++;
                if (callbacks == total) done(err, res);
            });
        })(i, arr[i]);
    }
}

runStack(stack, function(err, result) {
    console.log(err, result); // "null, [15, 12]"
});