Kristjan Kirpu
Kristjan Kirpu

Reputation: 682

Async parallel with object only last result

I'm having an issue with async parallel. This is my current code:

// Tasks object for async
var Tasks = {};
// Go through the items
for(index in items) {
    var itemName = items[index];
    Tasks[index] = function(callback) {
        self._requestItem(currency, appID, itemName, function(err, item) {
            if( err) {
                callback(err, null);
                return;
            }

            callback(null, { "name": itemName, "data": item });
        });
    }
}
// Go through tasks, using async parallel
this._async.parallel(Tasks, function(err, results) {
    console.log(err, results);
});

Each items entry is unique. But when the parallel finishes it shows every result like the last one. For example if I have 3 items in items then async results outputs 0, 1 the same as 2.

null { '0':
   { name: 'Test 3',
     data:
      { success: true,
        price: 17.02 } },
  '1':
   { name: 'Test 3',
     data:
      { success: true,
        price: 17.02 } },
  '2':
   { name: 'Test 3',
     data:
      { success: true,
        price: 17.02 } } }

Why does it do this? If I use 2 items in items it again copies the result from 1 to 0.

Adding snippet of _requestItem as requested.

Manager.prototype._requestItem = function(currency, appID, itemName, callback) {
    var self = this;

    this._request({
        uri: this._uri,
        baseUrl: this._baseUrl,
        json: true
    }, function(err, res, body) {
        if( ! err && res.statusCode !== 200) {
            if(self._errorCodes[res.statusCode] !== undefined) {
                callback(self._errorCodes[res.statusCode], null);
            } else {
                callback('Unsuccessful response (' + res.statusCode + '). Is the API having issues?', null);
            }
        } else if( ! err && res.statusCode === 200) {
            callback(null, body);
        } else {
            callback(err, null);
        }
    });
}

Upvotes: 0

Views: 804

Answers (1)

yeiniel
yeiniel

Reputation: 2456

No matter what is the content of the body of the _requestItem() function the value of the name attribute on the response array elements shouldn't be the same if the elements of the items array are unique.

The only error i can see is the fact that index is declared as a global variable but this shouldn't be the cause of the problem.

I suggest you to inspect the content of the items variable before the code enters the for loop (to see if it has been corrupted before this point). Debugging is a good idea in this case.

A better implementation would be:

var tasks = items.map(function(itemName){
  return function(callback) {
    self._requestItem(currency, appID, itemName, function(err, item) {
        if( err) {
            callback(err, null);
            return;
        }

        callback(null, { "name": itemName, "data": item });
    });
  }
});

// Go through tasks, using async parallel
this._async.parallel(tasks, function(err, results) {
  console.log(err, results);
});

Upvotes: 2

Related Questions