Async.js map function only showing results of the last iteration?

121 views
Skip to first unread message

Justin Maat

unread,
Jan 26, 2015, 10:22:37 AM1/26/15
to nod...@googlegroups.com
Sorry for the title, but I can't think of an easier way to word this.  
  
I'm trying to use the async library with Node.js to run 3 asynchronous functions and do some operation on the results of all 3.  From what I understand, the map() function allows me to run all 3 and apply an argument to an iterator, then provide a callback to operate on the results of all 3 async functions (stored in an array).  

The results are showing 3 successful responses, but they all contain the data from that last (3rd) function run, the other 2 are overwritten for some reason.

For example,

    /**map the array of exchange names through the iterator function
     * xchange is an external library which has functions of the form -
     * xchange.bitstamp.ticker(callback), xchange.bitfinex.ticker(callback), etc..
     */
    var xchange = require("xchange.js"),
        async = require("async");

    async.map([ "bitfinex", "bitstamp", "okcoin" ], 
    function(item, callback) {
    xchange[item].ticker(function(err, body) {
    console.log("item: " + item);
    console.log(body);
   
    return callback(err, body);
    });
    }, function(err, results) {
    console.log(results);
    });

    
    //print out
item: bitstamp
    { bid: 275.16,
      ask: 275.21,
      low: 245,
      high: 309.9,
      volume: 54017.1092978,
      timestamp: 1422283998 }
    item: okcoin
    { bid: 279.25,
      ask: 280.44,
      low: 242.93,
      high: 310.57,
      volume: 29342.543,
      timestamp: 1422284015 }
    item: bitfinex
    { bid: 279.2,
      ask: 279.77,
      low: 246.59,
      high: 315,
      volume: 165380.17021898,
      timestamp: 1422284011.1361156 }

    //Why are these all from the last run?  Should be the results of all 3 above
    [ { bid: 279.2,
        ask: 279.77,
        low: 246.59,
        high: 315,
        volume: 165380.17021898,
        timestamp: 1422284011.1361156 },
      { bid: 279.2,
        ask: 279.77,
        low: 246.59,
        high: 315,
        volume: 165380.17021898,
        timestamp: 1422284011.1361156 },
      { bid: 279.2,
        ask: 279.77,
        low: 246.59,
        high: 315,
        volume: 165380.17021898,
        timestamp: 1422284011.1361156 } ]

  
Basically the xchange ticker function uses the [request][2] module to call an http request on each ticker api.  The results (somewhat transformed) are returned.  

I'm able to run the following code with no errors, so I'm certain it has something to do with my xchange library code.
  
Any tips or ideas on what could cause this?  


Adrien Risser

unread,
Jan 26, 2015, 11:03:49 AM1/26/15
to nod...@googlegroups.com
Hi,

My only guess without looking at your code would be that the "body" passed to your ticker callback is overwritten / pointing to the same object.

// Pseudo code:

/* inside xchange module */

var obj = {};

/* main.js */

callback(err, obj);

/* inside async.map */

results.push(obj);

/* "end" callback */

console.log(results);

// [obj, obj, obj]

Try this:

console.log(results[0] === results[1]);

If true, then something like above might be happening.
If not, then new objects are created but values are the same (your method routing may be faulty).

Cheers,

--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/2828763a-2681-43f3-a8c7-0250cbd3fb5d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Adrien Risser,
Freelance Node.js Consultant

Justin Maat

unread,
Jan 26, 2015, 11:31:01 AM1/26/15
to nod...@googlegroups.com
Well that totally is the correct answer :)  But now I can't figure out why?

Running your code returned true which helped figure it out.
console.log(results[0] === results[1]);  

I then tried to take a deep copy of the body object and passing that into the callback like so...  and voila... the response looks correct.  

return callback(err, JSON.parse(JSON.stringify(body)));

Justin Maat

unread,
Jan 26, 2015, 11:35:52 AM1/26/15
to nod...@googlegroups.com
Ok, Digging deeper into xchange.js , it looks like I'm transforming the response but re-using the same object which is causing the error.

Thanks for the help!!  This actually taught me a bit :)
Reply all
Reply to author
Forward
0 new messages