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

Variable is overwritten in asynchronous function with async.forEach loop

本文关键字:async 覆盖 forEach 循环 异步 函数 变量      更新时间:2023-09-26

我偶然发现(或者当然是我自己创造的)一个错误,我不能在我的头脑中建模。我使用webdriverio客户端使用不同的id和解析结果的HTML迭代调用URL。但是,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变量总是返回最后一个元素,尽管我可以看到它使用不同的API id和不同的数据。我认为错误在于当我得到HTML并返回它,但我不能说为什么,也没有任何我的修复工作。

希望有比我更熟练的人能发现这个错误。

提前感谢,克里斯。

更新/解决方案-参见下面的解决方案

我不确定我是否很好地理解了上下文,但html变量没有被覆盖,它只是你从自我检索的最后一块。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并行执行函数,而我需要的函数是异步的。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);
});