Node js + multiple nested inner functions with callback
Asked Answered
W

1

6

I have nested inner functions with callback that are with in the single function(abcd).

I need to call abcd function from outside using async and return the response.

var listFunctions = {
    test1 : function(objectData, callbackData) {
        //have logic and retrun data
        callbackData(null, "a");
    },
    test2 : function(objectData, callbackData) {
        //have logic and retrun data
        callbackData(null, "b");
    },
    test3 : function(objectData, callbackData) {
        //have logic and retrun data
        callbackData(null, "c");
    },
    test4 : function(objectData, callbackData) {
        //have logic and retrun data
        callbackData(null, "d");
    },
    test5 : function(objectData, callbackData) {
        //have logic and retrun data
        callbackData(null, "e");
    }
};

function abcd(objectData, clb) {

    listFunctions.test1(objectData, function(err, data1) {
        listFunctions.test1(data1, function(err, data2) {
            listFunctions.test1(data2, function(err, data3) {
                listFunctions.test1(data3, function(err, data4) {
                    listFunctions.test1(data4, function(err, data5) {
                        return clb;
                    });
                });
            });
        });
    });
};

data object in array

 var objectData = [{"id":1, "name" : "abcd"},{"id":2, "name" : "abc2d"},{"id":3, "name" : "3abcd"},{"id":4, "name" : "4abcd"}];

initalFunction(objectData, function(response) {
    console.log(response);
});

function initalFunction(objectData, result) {

    async.each(objectData, function(dataValues, callback) {
        abcd(dataValues, function(response) {
            console.log(response);
        });

    }, function(err) {
        return result;
        //Need to re
    });
}

Need to iterate all array of objects using node js async using initalFunction function.

In above I added my code, Please suggest the correct way.

Whitsunday answered 3/3, 2016 at 10:23 Comment(0)
S
0

I am not sure if I understood what exactly you are trying to achieve but I will give it a try.

The first problem is that you can't return a value for your outer function within an inner callback function (see https://mcmap.net/q/73195/-how-to-return-value-from-an-asynchronous-callback-function-duplicate for more information on this).

Additionally you are returning the callback function not the result.

This is what I think you actually wanted to do:

var async = require("async");

var listFunctions = {
    test1: function(objectData, callbackData) {
        objectData.name += ":a";
        callbackData(null, objectData);
    },
    test2: function(objectData, callbackData) {
        objectData.name += ":b";
        objectData.foo = "bar";
        callbackData(null, objectData);
    },
    test3: function(objectData, callbackData) {
        objectData.name += ":c";
        callbackData(null, objectData);
    },
    test4: function(objectData, callbackData) {
        objectData.name += ":d";
        callbackData(null, objectData);
    },
    test5: function(objectData, callbackData) {
        objectData.name += ":e";
        callbackData(null, objectData);
    }
};

function abcd(objectData, cb) {
    listFunctions.test1(objectData, function(err, data1) {
        listFunctions.test2(data1, function(err, data2) {
            listFunctions.test3(data2, function(err, data3) {
                listFunctions.test4(data3, function(err, data4) {
                    listFunctions.test5(data4, function(err, data5) {
                        cb(err, data5);
                    });
                });
            });
        });
    });
}

function initalFunction(objectData, cb) {
    var results = [];

    async.each(objectData, function(dataValues, done) {
        abcd(dataValues, function(err, response) {
            results.push(response);
            done();
        });
    }, function(err) {
        cb(err, results);
    });
}

var objectData = [{id:1,name:"abcd"},{id:2,name:"abc2d"},{id:3,name:"3abcd"},{id:4,name:"4abcd"}];

initalFunction(objectData, function(err, response) {
    if (err) {
        console.log(err.stack);
        return;
    }
    console.log("Result:", response);
});

Now lets use async.seq and async.map to simplify this:

var async = require("async");

var listFunctions = {
    test1: function(objectData, callbackData) {
        objectData.name += ":a";
        callbackData(null, objectData);
    },
    test2: function(objectData, callbackData) {
        objectData.name += ":b";
        objectData.foo = "bar";
        callbackData(null, objectData);
    },
    test3: function(objectData, callbackData) {
        objectData.name += ":c";
        callbackData(null, objectData);
    },
    test4: function(objectData, callbackData) {
        objectData.name += ":d";
        callbackData(null, objectData);
    },
    test5: function(objectData, callbackData) {
        objectData.name += ":e";
        callbackData(null, objectData);
    }
};

var abcd=async.seq.apply(null, [
    listFunctions.test1,
    listFunctions.test2,
    listFunctions.test3,
    listFunctions.test4,
    listFunctions.test5
]);

function initialFunction(objectData, cb) {
    async.map(objectData, abcd, cb);
}

var objectData = [{id:1,name:"abcd"},{id:2,name:"abc2d"},{id:3,name:"3abcd"},{id:4,name:"4abcd"}];

initialFunction(objectData, function(err, response) {
    if (err) {
        console.log(err.stack);
        return;
    }
    console.log("Result:", response);
});

If you can change listFunctions from object to array:

var async = require("async");

var listFunctions = [
    function test1(objectData, callbackData) {
        objectData.name += ":a";
        callbackData(null, objectData);
    },
    function test2(objectData, callbackData) {
        objectData.name += ":b";
        objectData.foo = "bar";
        callbackData(null, objectData);
    },
    function test3(objectData, callbackData) {
        objectData.name += ":c";
        callbackData(null, objectData);
    },
    function test4(objectData, callbackData) {
        objectData.name += ":d";
        callbackData(null, objectData);
    },
    function test5(objectData, callbackData) {
        objectData.name += ":e";
        callbackData(null, objectData);
    }
];

function initialFunction(objectData, cb) {
    async.map(objectData, async.seq.apply(null, listFunctions), cb);
}

var objectData = [{id:1,name:"abcd"},{id:2,name:"abc2d"},{id:3,name:"3abcd"},{id:4,name:"4abcd"}];

initialFunction(objectData, function(err, response) {
    if (err) {
        return console.error(err.stack);
    }
    console.log("Result:", response);
});

if not but still need to handle dynamic listFunctions:

function initialFunction(objectData, cb) {
    var list = Object.keys(listFunctions).map(function(name) {
        return listFunctions[name];
    });
    async.map(objectData, async.seq.apply(null, list), cb);
}

I hope this helps.

Skirting answered 7/3, 2016 at 12:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.