[英]How do I iterate over an async function without completely skipping over all the steps in the function?
這是我的 repo 的 github 頁面的鏈接,因此您可以正確理解我的意思。
我目前在嘗試使其遞歸時遇到我的triviaGame
function 的問題,但從某種意義上說,這對我來說有點“適得其反”。
回答完第一個問題后,您會注意到,一切似乎都很好。 它很好地進入下一個問題。 不過在那之后,它的迭代似乎翻了一番? 下一個答案跳過 2。之后是 4。最后是剩下的 2(加起來是 10,因為我是如何迭代它們的)。
我如何能夠正確地迭代遞歸 function,所以它正確調用了所有 10 次,然后在完成后返回?
幾個小時以來一直在為此苦苦掙扎,但似乎無法讓它發揮作用。 我的 javascript 代碼如下,對於它可能給您帶來的任何麻煩,我們深表歉意。 我知道我做出了一些有問題的編程決定。 忽略一些注釋掉的東西,它還沒有完成代碼。 我是一個初學者,希望一旦我了解了這里發生的事情,它會一直伴隨着我,並且我不會再犯這樣的愚蠢錯誤。
const _URL = "https://opentdb.com/api.php?amount=1&category=27&type=multiple";
const _questionHTML = document.getElementById("question");
const _answerOne = document.getElementById("answer-1");
const _answerTwo = document.getElementById("answer-2");
const _answerThree = document.getElementById("answer-3");
const _answerFour = document.getElementById("answer-4");
const btns = document.querySelectorAll("button[id^=answer-]");
var runCount = 1;
var correct = 0;
// Credits to my friend Jonah for teaching me how to cache data that I get from an API call.
var triviaData = null;
async function getTrivia() {
return fetch("https://opentdb.com/api.php?amount=1&category=27&type=multiple")
.then((res) => res.json())
.then((res) => {
triviaData = res;
return res;
});
}
// anywhere I want the trivia data:
// const trivia = await getTrivia() --- makes the call, or uses the cached data
const shuffleArray = (array) => {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
};
async function triviaGame() {
const trivia = await getTrivia();
async function appendData() {
let totalAnswers = [
...trivia.results[0].incorrect_answers,
trivia.results[0].correct_answer,
];
// Apparently I need 2 different arrays to sort them because array variables are stored by reference? Learn something new everyday I guess.
let totalAnswers2 = [...totalAnswers];
let sorted = shuffleArray(totalAnswers2);
// Ensures the proper symbol shows instead of the HTML entities
const doc = new DOMParser().parseFromString(
trivia.results[0].question,
"text/html"
);
_questionHTML.textContent = doc.documentElement.textContent;
console.log(trivia.results[0].correct_answer, "- Correct Answer");
// Appends info to the DOM
_answerOne.textContent = sorted[0];
_answerTwo.textContent = sorted[1];
_answerThree.textContent = sorted[2];
_answerFour.textContent = sorted[3];
}
async function checkAnswer() {
btns.forEach((btn) => {
btn.addEventListener("click", (event) => {
console.log(runCount);
if (event.target.textContent === trivia.results[0].correct_answer) {
event.target.style.backgroundColor = "#52D452";
// Disables all buttons after one has been clicked.
btns.forEach((btn) => {
btn.disabled = true;
});
setTimeout(() => {
if (runCount === 10) {
return;
}
runCount++;
correct++;
btns.forEach((btn) => {
btn.disabled = false;
});
btn.style.backgroundColor = "";
document.getElementById(
"amount-correct"
).textContent = `${correct}/10`;
triviaGame();
}, 2000);
} else {
event.target.style.backgroundColor = "#FF3D33";
btns.forEach((btn) => {
btn.disabled = true;
});
// document.getElementById("correct-text").textContent =
// trivia.results[0].correct_answer;
// document.getElementById("correct-answer").style.visibility =
// "visible";
setTimeout(() => {
if (runCount === 10) {
return;
}
// document.getElementById("correct-answer").style.visibility =
// "hidden";
btns.forEach((btn) => {
btn.disabled = false;
btn.style.backgroundColor = "";
});
runCount++;
triviaGame();
}, 3500);
}
});
});
}
checkAnswer();
appendData();
}
triviaGame();
任何/所有回復都非常感謝和resected。 我可以使用你們願意給我的任何幫助。 過去的 6 個小時對我來說簡直就是地獄,哈哈。
單擊答案后,它會跳過問題,因為每次單擊按鈕時,都會將另一個事件偵聽器添加到按鈕中,而原始事件偵聽器處於活動狀態:
triviaGame()
運行使checkAnswer()
運行,從而將事件偵聽器添加到每個按鈕。triviaGame()
運行,使checkAnswer()
運行,為每個按鈕添加事件偵聽器。triviaGame()
運行兩次(從附加的 2 個偵聽器),這使得checkAnswer()
運行兩次,其中兩個調用都將事件偵聽器添加到每個按鈕。為了解決這個問題,我將checkAnswer()
的內容移到了任何函數之外,因此它只運行一次。 但是,這樣做會失去對上 scope 變量trivia
的引用。 為了解決這個問題,我使用了triviaData
變量來代替checkAnswer()
可以訪問的變量,並且我更改了appendData()
中的引用以匹配它。 現在, triviaGame()
function 只存在於里面調用appendData()
function; 這沒什么意義,所以我將這兩個函數合並為一個 function,而不是兩個相互嵌套。
const _URL = "https://opentdb.com/api.php?amount=1&category=27&type=multiple"; const _questionHTML = document.getElementById("question"); const _answerOne = document.getElementById("answer-1"); const _answerTwo = document.getElementById("answer-2"); const _answerThree = document.getElementById("answer-3"); const _answerFour = document.getElementById("answer-4"); const btns = document.querySelectorAll("button[id^=answer-]"); var runCount = 1; var correct = 0; // Credits to my friend Jonah for teaching me how to cache data that I get from an API call. var triviaData = null; async function getTrivia() { return fetch("https://opentdb.com/api.php?amount=1&category=27&type=multiple").then((res) => res.json()).then((res) => { triviaData = res; return res; }); } // anywhere I want the trivia data: // const trivia = await getTrivia() --- makes the call, or uses the cached data const shuffleArray = (array) => { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); const temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; }; async function appendData() { triviaData = await getTrivia(); let totalAnswers = [...triviaData.results[0].incorrect_answers, triviaData.results[0].correct_answer, ]; // Apparently I need 2 different arrays to sort them because array variables are stored by reference? Learn something new everyday I guess. let totalAnswers2 = [...totalAnswers]; let sorted = shuffleArray(totalAnswers2); // Ensures the proper symbol shows instead of the HTML entities const doc = new DOMParser().parseFromString( triviaData.results[0].question, "text/html" ); _questionHTML.textContent = doc.documentElement.textContent; console.log(triviaData.results[0].correct_answer, "- Correct Answer"); // Appends info to the DOM _answerOne.textContent = sorted[0]; _answerTwo.textContent = sorted[1]; _answerThree.textContent = sorted[2]; _answerFour.textContent = sorted[3]; } btns.forEach((btn) => { btn.addEventListener("click", (event) => { console.log(runCount); if (event.target.textContent === triviaData.results[0].correct_answer) { event.target.style.backgroundColor = "#52D452"; // Disables all buttons after one has been clicked. btns.forEach((btn) => { btn.disabled = true; }); setTimeout(() => { if (runCount === 10) { return; } runCount++; correct++; btns.forEach((btn) => { btn.disabled = false; }); btn.style.backgroundColor = ""; document.getElementById( "amount-correct" ).textContent = `${correct}/10`; appendData(); }, 2000); } else { event.target.style.backgroundColor = "#FF3D33"; btns.forEach((btn) => { btn.disabled = true; }); // document.getElementById("correct-text").textContent = // trivia.results[0].correct_answer; // document.getElementById("correct-answer").style.visibility = // "visible"; setTimeout(() => { if (runCount === 10) { return; } // document.getElementById("correct-answer").style.visibility = // "hidden"; btns.forEach((btn) => { btn.disabled = false; btn.style.backgroundColor = ""; }); runCount++; appendData(); }, 3500); } }); }); appendData();
<div id="amount-correct"></div> <h1 id="question"></h1> <button id="answer-1"></button> <button id="answer-2"></button> <button id="answer-3"></button> <button id="answer-4"></button>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.