递增循环但它在最后递增

Increment loop but it increments at the end

我正在尝试使用递增循环,但我希望它在循环结束时递增。可悲的是,每当我简单地将 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

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

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

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

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

希望我理解正确。

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

你可以试试里面的递归。 i,x 可能有一些错误,但你明白了。

你首先执行 i=1 和 x=1,操作完成后(然后)你调用 next 直到所有元素都被执行。

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)

正如评论所暗示的那样,这实际上可能是循环内异步调用 (Tesseract...then) 的问题。当 then 中的函数被调用时,您的 xi 的值已经移动,因此您不会得到您期望的结果。

解决此问题的一种方法是使用 'closure' - 创建一个函数,该函数根据 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));
    }
}

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

那么,假设您有这个循环:

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

它会打印这个,对吗?

0
1
2
3
4
5
6
7
8
9

但是,您不会直接在循环内打印您的值,而是作为承诺的后续操作。这使得这段代码 异步 。这意味着它 不必在您调用它的那一刻执行 。我这里没有 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);} 在我的例子中)异步函数 "schedules" 尽快执行操作,但是这个 "soon" 并不比循环快。所以,循环完成执行但我们的回调没有被调用,一次都没有!由于你没有用let声明i,它是一个全局变量,所以只有一个i。由于循环结束,i 变量的值已经是 10

它曾经是一件很难解决的事情,但是在 ES6 中它非常简单:用 let!

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

let-ed 变量 has a new binding at each iteration of the loop,所以实际上你有 10 个变量叫做 i。您的函数的闭包将只能访问具有正确值的函数!