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

标签 javascript promise bluebird

我天真地认为我可以将 .map() 链接到 Promise.map() 但看来我错了。当并发性很高时,我遇到了一个恼人的问题:通过单元测试但在现实世界测试中失败。我认为这使得这成为 Stack Overflow 上值得注意的问题。

我更改了代码以使用通常的 .then() 模式,现在它似乎每次都能工作。

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

下面是随机失败的代码(当并发性较高时),而在低并发性单元测试中似乎始终有效。请注意所有称为返回 promise 的函数。

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

最佳答案

那个 counts = []; 赋值是可疑的,似乎 create a global variable 。这会导致各种问题,包括引用异步方法并发执行中最新数组的计数。另外,在您的工作代码中,您有用于相同目的的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 };
    });
  });
};

关于javascript - Promise.map.map 链在并发时失败但通过单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43331451/

相关文章:

javascript - bluebird promise ——履行顺序不正确?

javascript - 将无限循环中的等待转换为原始 promise.then

javascript - 可以从一系列 promise 中删除 promise 吗?

javascript - WinJS 中的条件 promise

javascript - 当你想要所有结果而不考虑任何拒绝时,使用什么而不是 Promise.all()

javascript - 为什么在回调中取消 bluebird promise 会停止 setInterval?

Javascript 搜索从结尾开始并在另一个字符串停止的字符串

javascript - 如何防止单击按钮时发送水印文本?

javascript - 使用 HTML 文本字段沿 SVG textPpath 更新文本

javascript - 如何在 JavaScript 正则表达式匹配中查找组索引?