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

如何让JavaScript函数等待异步答题校验结果后执行棋子移动?

解决异步答题后触发棋子移动的问题

你卡到了异步操作的经典坑点——你的getQuestion()里用了AJAX,这是异步执行的,所以当你写if(getQuestion())时,getQuestion()会立刻执行完毕(此时AJAX请求还在后台跑,函数实际返回undefined),根本等不到答题结果返回,自然没法触发后续的棋子移动逻辑。

我给你两种靠谱的解决方案,都是基于Promise来处理异步流程的,你可以选一种适合你的:

方案一:用Promise + .then()处理

首先重构getQuestion()函数,让它返回一个Promise,这样我们就能等待答题结果:

function getQuestion() {
  // 保留你原来展示问题的逻辑(比如渲染表单到#ajax-panel)
  
  // 返回Promise对象,用来包裹异步的AJAX请求
  return new Promise((resolve, reject) => {
    // 用.one()绑定提交事件,避免重复绑定导致多次触发
    $(document).one("submit","form#ajax-panel", function(event){
      event.preventDefault();
      
      const dataObj2 = {
        answer: $("#answer option:selected").val(),
        answerWriten: $("#answerWrite").val(),
        correctAnswer: $("#correctAnswer").val(),
        difficulty: $("#questionDifficulty").val(),
      };
      console.log(dataObj2);
      
      $.ajax({
        url: 'ajax/checkAnswer.php',
        type: 'POST',
        dataType: 'json',
        data: dataObj2,
      })
      .done(function(data2) {
        console.log("Checking step completed");
        $('#ajax-panel').empty();
        if (data2.answer === data2.correct) {
          console.log("true");
          $('#ajax-panel').append("<p>Točno!</p>");
          resolve(true); // 答题正确,通知Promise返回true
        } else {
          console.log("false");
          $('#ajax-panel').append("<p>Netočno!</p>");
          resolve(false); // 答题错误,通知Promise返回false
        }
      })
      .fail(function(error) {
        console.error("答题验证请求失败:", error);
        $('#ajax-panel').empty().append("<p>Došlo je do greške prilikom provjere odgovora!</p>");
        reject(error); // 请求失败时触发reject,用于捕获错误
      });
    });
  });
}

然后修改你的点击触发逻辑,用.then()等待答题结果返回后再执行移动:

// 替换成你实际触发移动的按钮选择器
$(".move-trigger-button").on("click", function() {
  getQuestion()
    .then(isAnswerCorrect => {
      if (isAnswerCorrect) {
        // 答题正确,执行棋子移动
        greenPieces[i].moveSmart(diceResult);
      } else {
        // 答题错误,可添加提示或直接跳过
        console.log("Odgovor je netočan, figura se ne pomiče!");
      }
    })
    .catch(error => {
      // 处理请求失败的情况
      console.error("Greška:", error);
    });
});

方案二:用async/await(更接近同步代码的写法)

如果你觉得链式的.then()看着别扭,可以用async/await语法,代码会更清爽:

getQuestion()的重构和方案一完全一样,只需要修改点击事件的处理函数为async函数:

$(".move-trigger-button").on("click", async function() {
  try {
    // await会等待Promise的结果返回
    const isAnswerCorrect = await getQuestion();
    if (isAnswerCorrect) {
      greenPieces[i].moveSmart(diceResult);
    } else {
      console.log("Odgovor je netočan, figura se ne pomiče!");
    }
  } catch (error) {
    console.error("Greška prilikom provjere odgovora:", error);
  }
});

为什么原来的方法不行?

你之前的getQuestion()里,return true/false是写在AJAX的.done()回调里的——这个return只属于那个回调函数,根本不会成为getQuestion()的返回值。AJAX是异步的,当你调用getQuestion()时,浏览器会立刻发送请求,但函数本身会直接执行完,返回undefined,所以你的if(getQuestion())永远是if(undefined)(等价于false),自然不会触发移动逻辑。

用Promise的话,我们把异步操作的结果通过resolve()传递出来,再用.then()或者await等待这个结果,就能保证只有在答题结果明确后,才会判断是否移动棋子。

内容的提问来源于stack exchange,提问作者Antonio Mikulić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:58:26