Promise.map.map链在并发但是通过单元测试时失败

时间:2017-04-10 19:25:56

标签: javascript promise bluebird

我天真地以为我可以将.map()链接到Promise.map(),但看起来我错了。我遇到了传递单元测试的烦人问题,但在并发性很高时却没有通过实际测试。我认为这使得Stack Overflow值得注意。

我将代码更改为使用通常的.then()模式,现在似乎每次都有效。

这里的问题是不同于JS中的数组我不能将.map()链接到Promise.map()或者我做错了什么?我注意到我在工作版本中清理了一些lint问题,但这似乎并没有对行为产生影响。

下面是随机失败的代码(当并发性很高时)以及在低并发单元测试中似乎一直工作的代码。注意所有称为return promises的函数。

// this has concurrency issues. occasionally the function
// returns [{ key: undefined: val: correct }]
db.assocThreeFewCountsGet = function(manyid, atype) {
  counts = [];
  return db.assocThreeFewDistinctGet(manyid, atype)
  .then(r => {
    console.log('Distinct', r);   // shows there are valid IDs
    counts = r;
    return Promise.map(r, fewid => {
      return db.assocCount(manyid, fewid);
    }).map((el, idx) => {
      return { key: counts[idx], val: el };
    });
  });
};

// this appears to work correctly.  key: and val: are correct
db.assocThreeFewCountsGet = function(manyid, atype) {
  var ids;
  return db.assocThreeFewDistinctGet(manyid, atype)
  .then(r => {
    ids = r;
    console.log('Distinct IDs:', ids);  // shows there are valid IDs
    return Promise.map(ids, fewid => {
      return db.assocCount(manyid, fewid);
    });
  }).then(counters => {
    return counters.map((el, idx) => {
      return { key: ids[idx], val: el };
    });
  });
};

1 个答案:

答案 0 :(得分:1)

counts = [];分配是可疑的,似乎create a global variable。这会导致各种问题,包括counts引用异步方法的并发执行中的最新数组。同样在您的工作代码中,您有var ids用于相同的目的,这是每次调用的本地代码。

如果您在其他地方不需要counts,请使用

修复您的代码
db.assocThreeFewCountsGet = function(manyid, atype) {
  return db.assocThreeFewDistinctGet(manyid, atype)
  .then(counts => {
    console.log('Distinct', counts);   // shows there are valid IDs
    return Promise.map(counts, fewid => {
      return db.assocCount(manyid, fewid);
    }).map((el, idx) => {
      return { key: counts[idx], val: el };
    });
  });
};