James Ko
James Ko

Reputation: 34539

Node.js async: How to combine multiple iterators with map?

I'm new to Node.js. I'm trying to do some asynchronous work using async where I have multiple nested callbacks, and I'd like to combine some of the functions into one if possible. Here is the code:

function getInfo(info, callback) { /*...*/ }
function pushInfos(infos, callback) { /*...*/ }

function upload(release, callback) {
    async.map(release.files, getInfo, function(err, infos) {
        if (err)
            return callback(err);
        pushInfos(infos, function(error) {
            if (error)
                return callback(error);
            // do some more work...
        });
    });
}

I'm wondering if there is a way to combine the getInfo and pushInfo functions so that I only need one nested callback. Something like this:

function upload(release, callback) {
    async.xxxx(release.files, [ // What goes here?
        getInfo,
        pushInfos
    ],
    function(error) {
        // do some more work...
    }
}

Does such an API exist or do I have to deal with the extra code? I tried looking at the documentation on GitHub but I don't have much experience in asynchronous programming, so it's a bit over my head.

Upvotes: 0

Views: 753

Answers (2)

gfpacheco
gfpacheco

Reputation: 3215

Welcome, my friend, to callback hell!

If you're writing async code, I would advise you to take a look at Promises instead of callbacks.

But if you want to write your code with callbacks and async, the best you can do is something like this:

function getInfo(info, callback) { /*...*/ }
function pushInfos(infos, callback) { /*...*/ }

function upload(release, callback) {
    async.map(release.files, function(file, callback) {
        async.waterfall([
            async.apply(getInfo, file),
            pushInfos
        ], callback);
    }, function(err, infos) {
        if (err)
            return callback(err);
        // do some more work...
    });
}

EDIT

This answer actually behaves different than the question code, I misunderstand the question and wrote it wrong. James' answer behaves the same as the question code.

Upvotes: 1

James Ko
James Ko

Reputation: 34539

Well, after a bit of playing around and reading the documentation, here is what my code looks like now:

function upload(release, callback) {
    async.waterfall([
        async.apply(async.map, release.files, getInfo),
        pushInfos,
        function(next) {
            // do some work...
        }
    ], callback);
}

Upvotes: 1

Related Questions