【问题标题】:Javascript: increment counter variable inside loopJavascript:循环内递增计数器变量
【发布时间】:2017-06-27 17:30:35
【问题描述】:

我正在使用 Selenium 和 nodejs 来遍历一个 html 表格并将一个字符串从一个数组匹配到表格单元格中的字符串。

我的数组可能是 ["Name", "Address1", "Address2", "Address3",...] 并且 tr[1] 中的值将尝试与 Arr[0], tr[2] 匹配与 Arr[1] 等。

html 表格中的每个项目都会有一行,但如果没有数据,例如 Address2,则不会出现。

在这种情况下,tr[3] 会发现它无法与 Arr[3] 匹配。我不想移动到 tr[4],而是想看看 tr[3] 是否与 Arr[4] 匹配,然后是 Arr[5] 等。表中的项目将始终与数组中的项目的顺序相同,所以我不需要任何“不匹配”的数组项。

我已经发布了整个函数以防万一,但问题似乎很简单,因为我无法让“i = i - 1”将新值携带到下一个循环迭代中。

我已经证明我进入了 Else 部分,并且 i - 1 的值与我当时所期望的一样。

var retrieveData = function retrieveData(Arr){

j = 0

driver.findElements(webdriver.By.xpath("//*[@class='table-container']")).then (function(rows){

    rowCount = rows.length;
    console.log("Row count = " + rowCount);

}).then (function(fn){

    for (i = 1;i < rowCount + 1; i++){

        (function(i){

            var element = driver.findElement(webdriver.By.xpath("//div[@class='table-container']["+i+"]/div/strong/a"));

            element.getText().then(function(Type){

                var typefromArray = String(Arr[j].split(':')[0]);

                if (Type == typefromArray){

                    // Do something

                    j = j + 1;

                } else {

                    // Do something

                    i = i - 1 // My problem looks to be here, but may be in the transfer of this back up to the beginning of the loop       
                    j = j + 1;

                }

            });

        })(i);

    };

});

};

module.exports.retrieveData = retrieveData;

【问题讨论】:

  • 您在 IIFE 中有 i = i - 1。您也可以使用i--j++
  • 您好,感谢您的快速回复!如果字符串不匹配(即 If 语句返回 False),我只想减少计数器。如何将 i = i - 1(或 i--) 保留在 Else 之外?
  • 您在 (function(i){ 声明中隐藏了 i 的范围。

标签: javascript node.js for-loop


【解决方案1】:

您在传递索引的for 循环中使用IIFE。 看起来它是为了防止修改i

当你这样做时

i = i - 1

在你的函数结束时,它绝对没有任何影响,因为它只会影响你的函数中的i inside
Here's a good article 关于 JavaScript 中的变量范围。

但如果您仍想修改i,那么一种选择是简单地将其由匿名函数返回并分配给外部i 变量:

.then (function(fn){
    for (i = 1;i < rowCount + 1; i++){
        i = (function(i){
            var element = driver.findElement(webdriver.By.xpath("//div[@class='table-container']["+i+"]/div/strong/a"));
            element.getText().then(function(Type){
                var typefromArray = String(Arr[j].split(':')[0]);
                if (Type == typefromArray){
                    // Do something
                    j = j + 1;
                } else {
                    // Do something
                    i = i - 1 // My problem looks to be here, but may be in the transfer of this back up to the beginning of the loop       
                    j = j + 1;
                }
            });
            return i;
        })(i);
    };

这就是你所提问题的解决方案。


但我很确定您的代码中还会有其他问题,因为您使用的是同步循环,但在异步调用的函数(传递给 element.getText().then 的函数)中更新计数器。

我建议您研究一下如何在 JavaScript 中处理异步代码(您现在正在使用 Promises),或者就您尝试解决的更大问题提出一个更一般的问题,因为将会有还有一些需要克服的设计障碍。

以下是处理多个 Promise 时可能必须使用的模式示例(不打算复制粘贴,为简洁起见使用 ES2015):

.then(function(fn) {
  Promise.all(
    Array(rowCount).fill(true).map((_, i) => i + 1) // => [1..rowCount]
      .map(i => {
        const element = driver.findElement(webdriver.By.xpath("//div[@class='table-container']["+i+"]/div/strong/a"));
        return element.getText();
      })
  // Here we have an array of Promises that we pass to Promise.all
  //   so we can wait until all promises are resolved before executing
  //   the following .then
  ).then(types => types.filter(type => type === typefromArray)
                       .map(type => { /* doSomething */ });
});

【讨论】:

  • 感谢您花时间这么详细地回答。我还有很多东西要学!
  • 我已经研究过 Promise,但对它们的理解并不多,只是知道使用“.then”可以在调用任何代码之前阻止我的计数器变量递增。出于类似的原因,我将 IIFE (我只知道它是一个“闭包”,因此误解了第一个响应)包裹在它周围,因为输出到控制台在没有它的情况下为 i 提供了不正确的值(尽管它有效)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 2015-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
相关资源
最近更新 更多