递增循环,但在末尾递增

时间:2018-06-22 18:07:16

标签: javascript variables for-loop increment

我正在尝试使用增量循环,但我希望它在循环结束时增加。令人遗憾的是,每当我将i++放在循环的末尾时,它的行为就不会像我期望的那样。有人介意向我展示正确的做法吗?

引用的增量循环:

for (i = 1; i < 15; i++) {
  // do somthing here
}

这是我正在使用的循环:

for (i = 1; i < 15; i++) {
  for (x = 1; x < 15; x++) {
    var take = document.getElementById("row" + i + "sm" + x);

    Tesseract.recognize(take)
      .then(function(result) {
        console.log(result.text);
        // rows[i][x] = result.text;
      })
  }
}

我想做什么:

for (i = 1; i < 15) {
  for (x = 1; x < 15) {
    var take = document.getElementById("row" + i + "sm" + x);

    Tesseract.recognize(take)
      .then(function(result) {
        console.log(result.text);
        //rows[i][x] = result.text;
        x += 1;
      })
    i += 1;
  }
}

我正在使用for循环,因为我需要一个一个地迭代。如何在循环结束时适当地递增i

这是一段视频,用上下文解释了我的问题,并解释了为什么它不是ASYNC问题。抱歉,如果很难遵循,请尽快用音频更新它,以便我正确解释。

https://drive.google.com/file/d/1n1ZwNJif5Lb5zfLb2GPpBemObwpOqNf7/view

4 个答案:

答案 0 :(得分:1)

问题是第二个不等到第一个完成。

您可以在内部尝试递归。 i,x可能有一些错误,但是您明白了。

首先使用i = 1和x = 1执行,然后在操作完成后调用下一个,直到所有元素都执行完毕。

function execItem(i, x) {
    var take = document.getElementById("row" + i + "sm" + x);
    Tesseract.recognize(take)
    .then(function(result){
        rows[i][x] = result.text;
        if (i < 15 && x < 15) {
            if (i > 15) {
                x += 1
                i = 1
            } else {
                i += 1
            }
            execItem(i, x)

        } 
    })
}
execItem(1, 1)

答案 1 :(得分:0)

正如评论所暗示的那样,这实际上似乎是循环内异步调用(Tesseract...then)的问题。到then内的函数被调用时,您的xi的值已经移动,因此您无法获得预期的结果。

解决此问题的一种方法是使用“闭包”-制作一个函数,该函数根据ix的值创建另一个函数。

function getDisplayFunc(row, col) {
    function displayRecognisedText(result) {
      console.log(row, col, result.text);
     //rows[row][col] = result.text;
  }
  return displayRecognisedText;
}

for (i = 1; i < 15; i++) {
    for (x = 1; x < 15; x++) {
        var take = document.getElementById("row" + i + "sm" + x);
        Tesseract.recognize(take).then(getDisplayFunc(i, x));
    }
}

答案 2 :(得分:-1)

也许您应该尝试使用while循环。 像这样:

            while i < 15:
            //do something
            i += 1

对于两个变量:x,i具有嵌入:

            while x < 15:
                //do something
                while i < 15:
                    //do something2
                    i += 1
                x += 1

希望我能正确理解问题。

答案 3 :(得分:-1)

我猜@Mike发现了错误:您的代码是异步的。什么意思?

因此,假设您有以下循环:

for (i = 0; i < 10; i++) {
  console.log(i);
}

它将打印出来,对吧?

0
1
2
3
4
5
6
7
8
9

但是,您不直接在循环内打印值,而是作为对Promise的后续操作。这使得该代码异步。这意味着它不必在您调用它的确切时间执行。我这里没有Tesseract,所以我将使用另一个非常古老的技巧setTimeout()使循环异步:

for (i = 0; i < 10; i++) {
    setTimeout(function() {
      console.log(i);
    }, 0);
}

如果我运行它,我会得到:

10
10
10
10
10
10
10
10
10
10

发生的事情是,当我通过我们要执行的操作(在这种情况下,打印i值)到异步函数(在您的情况下为recognize().then(),在程序中为setTimeout()以我的情况为例)通过回调(在我的示例中为function() {console.log(i);}),异步函数“安排”了该操作以尽快执行,但此“很快”的执行速度并不比循环快。因此,循环完成了执行,但没有调用我们的回调,甚至没有一次!由于您没有使用i声明let,因此它是一个全局变量,因此仅存在一个i。并且自从循环结束以来,i变量的值已经是10

过去很难解决,但是使用ES6则非常简单:用i声明let

for (let i = 0; i < 10; i++) {
    setTimeout(function() {
      console.log(i);
    }, 0);
}

let版的变量has a new binding at each iteration of the loop,因此实际上您有10个名为i的变量。函数的关闭只能访问具有正确值的函数!