简体   繁体   中英

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

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 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?

I had a similar problem where it appeared that async map was rewriting the results to all the be same. I turns out it wasn't an async problem but a problem with what my function was returning as a result.

My problem was that I was passing an object to the result, and passing the same object, but changing the values within it each time. This ended up meaning I had an array of several references to a single object. So when I examined my result array it looked like it had returned the last object several times, when in reality I'd only returned one object several times and changed the values in it in each loop. I suspect you have the same issue.

If in your library you create an object, let's call it bitCoin, and then you return that on the first map loop, then you use the same bitCoin object and change the values within it and return on the second map loop, then the values for every reference to that object will also be updated, which means the first result will now look like your second result.

正如您在响应中链接的那样,在callback引用相同的对象,使map函数在每次迭代中覆盖该对象,这使最终结果成为同一对象的数组,特别是最后一次迭代。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM