Я делаю математическую игру на основе браузера и столкнулся с ошибкой зацикливания.
Числа генерируются от 0 до 20 и генерируются снова, если их сумма или разность (если применимо) выходит за пределы 0 или 20.
function mathFunction() {
//generates a value of 0 or 1 to dermine if the problem will be addition or subtraction (0 = + , 1 = -)
var sign = Math.floor(Math.random() * 2);
if (sign == 0) {
dsign = " + ";
} else {
dsign = " - ";
}
//generates two random values between 0 and 20
var num1 = Math.floor(Math.random() * 21);
var num2 = Math.floor(Math.random() * 21);
//if the sum of an addition problem is greater than 20, it calls mathFunction to make new values
if (sign == 0) {
if (num1 + num2 > 20) {
mathFunction();
}
//if the difference of a subtraction problem is less than 0, it calls mathFunction to make new values
} if (sign == 1) {
if (num1 - num2 < 0) {
mathFunction();
}
}
Переменные отправляются в функцию оценки.
//evalFunction is called when the button is clicked, and passes the 2 numbers and the sign value
document.getElementById("enterButton").addEventListener('mousedown', function() {
evalFunction(num1, num2, sign);
}, false);
}
function evalFunction(num1, num2, sign) {
var counter = 1;
alert("fire");
var answer = document.getElementById("answer").value;
Я добавил оповещения, чтобы следить за происходящим. Нажатие Enter в первый раз приведет к нормальному результату. Нажатие Enter после первой проблемы вызовет ошибки, которые кажутся результатом зацикливания функций.
//calls mathFunction to generate a new question
alert(counter + " num 1: " + num1);
alert(counter + " num 2: " + num2);
alert(counter + " answer: " + answer);
counter = counter + 1;
mathFunction();
}
//loads first question
window.onload = mathFunction();
Я вставил весь код в pastebin. Заранее благодарю за любой совет.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ошибка зацикливания возникает из-за того, что mathFunction() вызывает сам себя, если он недействителен.
Итак, стек вызовов выглядит примерно так:
mathFunction() --> mathFunction() --> mathFunction()
Когда mathFunction наверху стека завершается, следующий mathFunction() продолжает выполнение, как будто ничего не произошло.
Вместо mathFunction() попробуйте использовать функцию, которая возвращает математическую задачу в виде объекта:
function generateProblem() {
//generates a value of 0 or 1 to dermine if the problem will be addition or subtraction (0 = + , 1 = -)
var sign = Math.floor(Math.random() * 2);
if (sign == 0) {
dsign = " + ";
} else {
dsign = " - ";
}
//generates two random values between 0 and 20
var num1 = Math.floor(Math.random() * 21);
var num2 = Math.floor(Math.random() * 21);
//return the problem as an object
return {sign: dsign, first: num1, second: num2};
}
Затем поместите эту функцию-генератор проблем в цикл:
var problem;
while (true) {
problem = generateProblem();
//checks for addition, you can expand it to check for valid subtraction questions as well
if (problem.sign == " + ") {
if (problem.first + problem.second == 20) {
continue; //this problem isn't valid, so restart at the top of the loop
}
}
}
Таким образом, mathFunction () иногда вызывает саму себя. Когда это происходит, в результате накапливаются функции. Чтобы предотвратить это, поместите создание проблемы в функцию, а проверку проблемы в цикл. Таким образом, стек вызовов не будет накапливаться с помощью mathFunction ().