仅与对象的最后结果异步并行

Async parallel with object only last result

我遇到异步并行问题。这是我当前的代码:

// 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);
});

每个 items 条目都是唯一的。但是当并行完成时,它会像最后一个一样显示每个结果。例如,如果我在 items 中有 3 个项目,那么异步 results 输出 0、1 与 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 } } }

为什么要这样做?如果我在 items 中使用 2 个项目,它会再次将结果从 1 复制到 0。

根据要求添加 _requestItem 的片段。

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);
        }
    });
}

无论 _requestItem() 函数主体的内容是什么,如果 items 数组是唯一的。

我能看到的唯一错误是 index 被声明为全局变量,但这不应该是问题的原因。

我建议您在代码进入 for 循环之前检查 items 变量的内容(以查看它是否在此之前已损坏)。在这种情况下调试是个好主意。

更好的实施方式是:

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);
});