Async module error with parallel API requests

Async module error with parallel API requests

Problem

I’m a begginer in node.js and now I’m trying to get some API’s result. I’m using async module (https://github.com/caolan/async) to parallel the request so it can be optimized.

The problem is the code is returning an error that each time points to a different line (the “callback(err, data)” line) in a different API call

That’s is the error:

if (called) throw new Error("Callback was already called.");
                          ^
Error: Callback was already called.

I’m using the following function to request the API:

function getData(s, apiURL, getURL, callback) {

    var ht;
    if (s == 1) {
        ht = https;
    } else {
        ht = http;
    }

    var options = {
        hostname : apiURL,
        path : getURL,
        method : 'GET'
    }

    var content = "";

    ht.get(options, function(res) {
        console.log("Got response: " + res.statusCode);

        res.on("data", function(chunk) {

            content += chunk;
            //console.log(content);
            callback(content);
       });

    }).on('error', function(e) {
        console.log("Error: " + e.message);
        console.log(e.stack);
    });
}

To illustrate, this is how I’m using the async module:

var sources = sources.split(',')

    async.parallel({
        flickr : function(callback) {
            if (sources[0] == 1) {
                getData(0, 'api.flickr.com',
                "/services/rest/?method=flickr.photos.search&format=json&nojsoncallback=1&api_key=" + config.flickr.appid + "&per_page=5&tags=" + tags,

                function(data) {
                    callback(null, data); //here that the error may point
                });

            } else { callback(); }
        },
        instagram : function(callback) {
            if (sources[1] == 1) {

                getData(1, 'api.instagram.com',
                "/v1/tags/" + tags.split(',')[0] + "/media/recent?client_id=" + config.instagram,
                function(data) {                        
                    callback(null, data); //here that the error may point

                });
            } else { callback(); }
        } 
    }, function(err, results) {             
            console.log(results);
        });

Hope you can help me, thanks!

Problem courtesy of: fnnrodrigo

Solution

You are calling the callback function inside the data event (see the docs), which is triggered every time a chunk of data is received, that means several times.

Async.parallel is expecting the callback to be executed only once for each task.

To ensure only one callback per task, put the callback on an end event, for example.

Also, the error event should execute the callback as well.

Solution courtesy of: gargc

Discussion

Leave a Reply

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