使用 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);
});
我偶然发现(或者当然是我自己造成的)一个我无法在脑海中建模的错误。我使用具有不同 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);
});