使用 async.forEach 循环在异步函数中覆盖变量

Variable is overwritten in asynchronous function with async.forEach loop

我偶然发现(或者当然是我自己造成的)一个我无法在脑海中建模的错误。我使用具有不同 ID 的 webdriverio 客户端迭代调用 URL 并解析结果 HTML。 但是,html 变量被循环中的最后一个元素覆盖,这导致数组包含最后一个 html 变量值的多个副本:

async.forEach(test, function (id, callback) {
  self.url('https://<api-page>?id=' + id).getHTML('table tbody', true).then(function(html) {
          //Parse HTML
          parser.write(html);
          parser.end();

          //Add course to person, proceed to next.
          callback();
  });
}, function (err) {
  self.end().finally();
  res.json(person);
});

解析是使用 htmlparser2 NPM 库完成的。 html 变量总是 return 是最后一个元素,即使我可以看到它通过不同的 API id 和不同的数据。我认为错误在于我得到 ​​HTML 和 return 时,但我不能说为什么也没有我的任何修复工作。

希望比我更熟练的人能看到错误。

提前致谢, 克里斯

UPDATE/Solution - 请参阅下面的解决方案

我不确定我是否完全理解上下文,但是 html 变量没有被覆盖,它只是您从 self.url 函数调用中检索到的最后一块。如果你想将整个结果保存在一个变量中,你应该在每个循环中附加结果。可能,你需要这样的东西:

var html = '';

async.forEach(test, function (id, callback) {
  self.url('https://<api-page>?id=' + id).getHTML('table tbody', true).then(function (tmpHtml) {
    //Parse HTML
    parser.write(tmpHtml);
    parser.end();

    html += tmpHtml;
    //Add course to person, proceed to next.
    callback();
  });
}, function (err) {
  self.end().finally();
  res.json(person);
});

我终于弄明白了,我错过了 async.forEach 并行执行函数,而我需要的函数是 async.timesSeries,它循环执行函数,等待每个函数执行在开始下一个之前完成!我附上了下面的工作代码:

async.timesSeries(3, function(n, next) {
  self.url('<api-page>?id=' + n').then(function() {
    console.log("URL Opened");
  }).getHTML('table tbody', true).then(function(html) {
    console.log("getHTML");
    parser.write(html);
    parser.end();
    next();
  });
}, function(err, results) {
  //Add to person object!
  self.end().finally();
  res.json(person);
});