为什么我的页面会陷入死循环?
Why does my page fall into the infinite loop?
function randomNumber(){
var value;
var flag = false;
var tds = document.querySelectorAll('td');
do{
value = Math.round(Math.random() * (26 - 1) + 1);
for(var t = 0; t < tds.length; t++){
if(tds[t].innerHTML == value)
flag = true;
}
if(!flag){
return value;
}
}while(flag == true)
}
这个函数returns一个新td的innerHTML的随机数。如果有其他 tds 与此代码生成的编号相同,则循环再次开始。如果生成的数字是唯一的,我将其添加到新 td 的 innerHTML 中。但是我什至无法加载页面,因为我 运行 陷入了无限循环,但无论我多么努力,我都没有注意到这段代码的逻辑问题。
一旦你的循环找到 tds[t].innerHTML == value
的情况,它将 flag
设置为 true
- 此时你永远无法结束循环,因为你无处检查情况您可以将 flag
设置为 false
,这样您的循环条件将 始终 为真。
这是一个类似的例子,用一个数组来说明这一点。您可以看到,有时它会向数组中添加数字(在它找到新值的情况下),但有时循环会达到 5000 次迭代并退出(因为它从未找到新值),在这种情况下它会添加 undefined
到数组,因为函数没有返回任何东西。
const arr = []
function randomNumber(){
var value;
var flag = false;
var tds = arr
var iterations = 0
do {
value = Math.round(Math.random() * (26 - 1) + 1);
for(var t = 0; t < tds.length; t++){
if(tds.includes(value))
flag = true;
}
if(!flag){
return value;
}
iterations += 1
console.log(iterations)
} while(flag == true && iterations < 5000)
}
for (let i = 0;i<20;i+=1) {
arr.push(randomNumber())
}
console.log(arr)
当您的函数至少一次将 flag
设置为 true 时,它就结束了 - 它再也不会将其设置为 false。为了修复它,我添加了一行代码。
function randomNumber(){
var value;
var flag = false;
var tds = document.querySelectorAll('td');
do {
flag = false; // this line i added
value = Math.round(Math.random() * (26 - 1) + 1);
for(var t = 0; t < tds.length; t++){
if(tds[t].innerHTML == value)
flag = true;
}
if(!flag){
return value;
}
}while(flag == true)
}
我也会写一些更高效的代码给你
function randomNumber(){
var value;
var found = false;
var tds = document.querySelectorAll('td');
var existingIds = [];
tds.forEach(td => existingIds.push(td.innerHHML)); // fill up the ids
do {
value = Math.round(Math.random() * (26 - 1) + 1); // this line would make problems (comment below)
if (existingIds.indexOf(value) === -1) found = true; // check if value can be found in existing ids and if found - set dount to true (you can also return from here, but i would rather user break (if there was more code after this line, than use retur in the middle of any loop;
} while(found === false)
return value;
}
随机注释行:
- random() returns从0到1的数
- 如您所写 - 该值将是 1 到 26 之间的随机数(仅此值)。
- 如果所有值都已被使用,那么我们的循环将不会结束(当 1 到 26 之间的所有值都已被使用时,我们永远找不到未使用的 1 到 26 之间的值。
可以做什么
- 您可以添加一些计数器(如@Ben 所做的那样)并在这种情况下退出循环。
- 或者您可以将数字 26 提高到更高
- 您可以使用连续的数字(获取全部,取最大的一个,加 1 return 作为新数字)
你当然可以找到一些其他的方法来应对
function randomNumber(){
var value;
var flag = false;
var tds = document.querySelectorAll('td');
do{
value = Math.round(Math.random() * (26 - 1) + 1);
for(var t = 0; t < tds.length; t++){
if(tds[t].innerHTML == value)
flag = true;
}
if(!flag){
return value;
}
}while(flag == true)
}
这个函数returns一个新td的innerHTML的随机数。如果有其他 tds 与此代码生成的编号相同,则循环再次开始。如果生成的数字是唯一的,我将其添加到新 td 的 innerHTML 中。但是我什至无法加载页面,因为我 运行 陷入了无限循环,但无论我多么努力,我都没有注意到这段代码的逻辑问题。
一旦你的循环找到 tds[t].innerHTML == value
的情况,它将 flag
设置为 true
- 此时你永远无法结束循环,因为你无处检查情况您可以将 flag
设置为 false
,这样您的循环条件将 始终 为真。
这是一个类似的例子,用一个数组来说明这一点。您可以看到,有时它会向数组中添加数字(在它找到新值的情况下),但有时循环会达到 5000 次迭代并退出(因为它从未找到新值),在这种情况下它会添加 undefined
到数组,因为函数没有返回任何东西。
const arr = []
function randomNumber(){
var value;
var flag = false;
var tds = arr
var iterations = 0
do {
value = Math.round(Math.random() * (26 - 1) + 1);
for(var t = 0; t < tds.length; t++){
if(tds.includes(value))
flag = true;
}
if(!flag){
return value;
}
iterations += 1
console.log(iterations)
} while(flag == true && iterations < 5000)
}
for (let i = 0;i<20;i+=1) {
arr.push(randomNumber())
}
console.log(arr)
当您的函数至少一次将 flag
设置为 true 时,它就结束了 - 它再也不会将其设置为 false。为了修复它,我添加了一行代码。
function randomNumber(){
var value;
var flag = false;
var tds = document.querySelectorAll('td');
do {
flag = false; // this line i added
value = Math.round(Math.random() * (26 - 1) + 1);
for(var t = 0; t < tds.length; t++){
if(tds[t].innerHTML == value)
flag = true;
}
if(!flag){
return value;
}
}while(flag == true)
}
我也会写一些更高效的代码给你
function randomNumber(){
var value;
var found = false;
var tds = document.querySelectorAll('td');
var existingIds = [];
tds.forEach(td => existingIds.push(td.innerHHML)); // fill up the ids
do {
value = Math.round(Math.random() * (26 - 1) + 1); // this line would make problems (comment below)
if (existingIds.indexOf(value) === -1) found = true; // check if value can be found in existing ids and if found - set dount to true (you can also return from here, but i would rather user break (if there was more code after this line, than use retur in the middle of any loop;
} while(found === false)
return value;
}
随机注释行:
- random() returns从0到1的数
- 如您所写 - 该值将是 1 到 26 之间的随机数(仅此值)。
- 如果所有值都已被使用,那么我们的循环将不会结束(当 1 到 26 之间的所有值都已被使用时,我们永远找不到未使用的 1 到 26 之间的值。
可以做什么
- 您可以添加一些计数器(如@Ben 所做的那样)并在这种情况下退出循环。
- 或者您可以将数字 26 提高到更高
- 您可以使用连续的数字(获取全部,取最大的一个,加 1 return 作为新数字)
你当然可以找到一些其他的方法来应对