我正在尝试使用增量循环,但我希望它在循环结束时增加。令人遗憾的是,每当我将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
答案 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
内的函数被调用时,您的x
和i
的值已经移动,因此您无法获得预期的结果。
解决此问题的一种方法是使用“闭包”-制作一个函数,该函数根据i
和x
的值创建另一个函数。
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
的变量。函数的关闭只能访问具有正确值的函数!