You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复JavaScript中Firestore随机题目不等待Next按钮直接全部展示的问题

嘿,我完全懂你遇到的问题!你现在的代码里,runningExam函数的while循环会一口气把所有题目请求并渲染完——因为循环是同步执行的,Firestore的请求一完成就立刻调用renderQuestion,整个过程瞬间跑完,根本不会等用户点击Next按钮。

要解决这个问题,我们得换个思路:先把所有随机顺序的题目提前准备好,然后让Next按钮来控制逐个渲染,而不是让循环自动跑完所有步骤。下面是具体的修复方案:

核心思路

  1. 先一次性获取所有需要的题目,按随机顺序存入数组
  2. 维护一个「当前题目索引」,初始从0开始,先渲染第一题
  3. 给Next按钮绑定点击事件,每次点击就切换到数组里的下一题

修改后的代码

// 全局/闭包内存储题目列表和当前索引(根据你的代码结构调整作用域)
let questionsList = [];
let currentQuestionIndex = 0;

// 简化渲染函数,只需要传入题目文档即可
renderQuestion = (qDoc) => {
  q.innerHTML = qDoc.data().question;
  ans1.innerHTML = qDoc.data().a;
  ans2.innerHTML = qDoc.data().b;
  ans3.innerHTML = qDoc.data().c;
  ans4.innerHTML = qDoc.data().d;
};

// Next按钮的点击逻辑单独封装
function handleNextClick() {
  currentQuestionIndex++;
  if (currentQuestionIndex < questionsList.length) {
    // 还有题目,渲染下一题
    renderQuestion(questionsList[currentQuestionIndex]);
  } else {
    // 所有题目展示完毕,做收尾处理
    q.innerHTML = "考试结束!";
    next.disabled = true; // 禁用按钮防止重复点击
  }
}

runningExam = async (review) => {
  const totalQ = review.data().total_questions;
  let arr = [];
  // 初始化标记数组,避免重复选同一题
  for (let i = 0; i <= totalQ; i++) {
    arr.push(false);
  }
  let n = totalQ;

  // 先收集所有随机选中的题目文档
  while (n) {
    let randomNumber = getRandom(totalQ);
    if (!arr[randomNumber]) {
      arr[randomNumber] = true;
      const snapshot = await db
        .collection("examrooms")
        .doc(review.id)
        .collection("questions")
        .where("serial", "==", randomNumber)
        .get();
      // 因为serial是唯一序号,所以取第一个文档即可
      if (snapshot.docs.length > 0) {
        questionsList.push(snapshot.docs[0]);
      }
      n--;
    }
  }

  // 渲染第一题,并绑定Next按钮事件(确保只绑定一次)
  if (questionsList.length > 0) {
    renderQuestion(questionsList[currentQuestionIndex]);
    next.removeEventListener("click", handleNextClick);
    next.addEventListener("click", handleNextClick);
  }
};

关键改动说明

  • 去掉了原代码里循环内直接渲染的逻辑,改为先把所有题目存入questionsList数组
  • 用currentQuestionIndex记录当前显示的题目位置,通过Next按钮点击来推进索引
  • 单独封装handleNextClick函数处理切换逻辑,避免重复绑定事件
  • 因为serial是唯一的题目序号,所以不需要用forEach遍历snapshot,直接取第一个文档即可

这样修改后,程序会先渲染第一题,只有当用户点击Next按钮时,才会展示下一题,完全符合你的预期啦!

内容的提问来源于stack exchange,提问作者mahin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:32:48