簡體   English   中英

如何在不完全跳過 function 中的所有步驟的情況下迭代異步 function?

[英]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 個小時對我來說簡直就是地獄,哈哈。

單擊答案后,它會跳過問題,因為每次單擊按鈕時,都會將另一個事件偵聽器添加到按鈕中,而原始事件偵聽器處於活動狀態

  1. 在初始加載時: triviaGame()運行使checkAnswer()運行,從而將事件偵聽器添加到每個按鈕。
    按鈕上的事件監聽器:1。
  2. 單擊應答按鈕, triviaGame()運行,使checkAnswer()運行,為每個按鈕添加事件偵聽器。
    按鈕上的事件監聽器:2。
  3. 單擊應答按鈕, triviaGame()運行兩次(從附加的 2 個偵聽器),這使得checkAnswer()運行兩次,其中兩個調用都將事件偵聽器添加到每個按鈕。
    按鈕上的事件監聽器:4。
  4. 等等

為了解決這個問題,我將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM