Php 在第一次调用时执行两次多ajax调用

Php 在第一次调用时执行两次多ajax调用,php,jquery,ajax,laravel,Php,Jquery,Ajax,Laravel,我有一个计时器&我希望每次计时器归零时,向服务器发送一个Ajax请求,告诉我用户有多少硬币,同时减少1枚硬币。 除了Ajax第一次将请求发送到URL之外,它可以正常工作 只是第一次它减少了2枚硬币而不是1枚。 我只是想知道为什么会这样 javascript代码: <script> var timeout=false; $(document).ready(function () { match_timer(); }

我有一个计时器&我希望每次计时器归零时,向服务器发送一个Ajax请求,告诉我用户有多少硬币,同时减少1枚硬币。 除了Ajax第一次将请求发送到URL之外,它可以正常工作 只是第一次它减少了2枚硬币而不是1枚。 我只是想知道为什么会这样

javascript代码:

<script>
        var timeout=false;
        $(document).ready(function () {
            match_timer();
        })
    </script>

    <script>
        function match_timer() {
            var n = 5;
            var tm = setInterval(countDown, 1000);

            function countDown() {
                n--;
                document.getElementById('match-timer').innerHTML=n.toString();
                if (n === 0) {
                    clearInterval(tm);
                    get_question();
                    timeout=true;
                }
                if(timeout===true){
                    timeout=false;
                    match_timer();
                }
            }
        }
    </script>

    <script>
        function get_question() {

            $("#question").empty();
            $.ajax({
                url:'http://127.0.0.1:8000/get_another_question/',
                method: 'POST',
                data:{
                    "_token":"{{csrf_token()}}",
                },
                success:function (data) {


                           document.getElementById('question').innerHTML=data['title'];

                           $("#coin_balance").html(data['newCoinBalance']);


                }
            });
        }
    </script>

之所以会发生这种情况,是因为Ajax是异步操作,这意味着它将在不同的线程中执行,其余代码将正常继续,而无需等待Ajax调用完成。如果打开两个选项卡,并且请求同时来自两个选项卡,则可能会出现双减量。要克服这一点,您可以利用。因此,您的Laravel代码如下所示:

public function getAnotherMatchQuestion(){
  try{
    DB::beginTransaction();
    $user_id =auth()->user()->id;
    $user = \App\Models\User::find($user_id);
    $coin = $user->coin_balance;
    $coin -= 1;
    $user->coin_balance = $coin;
    $user->save();

    $question_id = mt_rand(1,15612);
    $getMatchQuestion = QuizQuestion::find($question_id)->only(['question']);
    $data = [
               'title' => $getMatchQuestion['question'],
               'newCoinBalance' => $coin
            ];
    DB::commit();
    return response()->json($data);
  }catch(Exception $e){
    DB::rollBack();
    return return response()->json(['error' => $e->getMessage()]);
  }
}
请注意这将保持数据的一致性,这意味着发出的请求数等于在不丢失任何数据的情况下服务的请求数

  • 双重检查您的网络,以便在开始时只有一个AJAX调用
  • 尝试随时间记录getAnotherMatchQuestion(例如,记录到文件),这样您就知道在AJAX进行时调用它的次数是一样多的
  • 在函数match_timer中,您可以使用call和resource重新定义n everytime调用match_timer。在继续之前(延迟1秒)
  • 最后:在调用不正确的情况下使用ajax错误

  • 我做到了,但我仍然有机会problem@hesmM你调用
    get_question()每5秒一次。对吗?您是否打开了多个选项卡?是的,我希望每次计时器变为零时减少一枚硬币,代码正常工作,但计时器第一次变为0时除外。不,只有一个tab@hesmM第一次在数据库中的值是多少?你的意思是值是5,在第一次请求后它变成了3?我手动将值设置为100,但在第一次请求后它变为98,而它必须是99。这个问题仅适用于第一次请求,之后一切正常
    
    public function getAnotherMatchQuestion(){
      try{
        DB::beginTransaction();
        $user_id =auth()->user()->id;
        $user = \App\Models\User::find($user_id);
        $coin = $user->coin_balance;
        $coin -= 1;
        $user->coin_balance = $coin;
        $user->save();
    
        $question_id = mt_rand(1,15612);
        $getMatchQuestion = QuizQuestion::find($question_id)->only(['question']);
        $data = [
                   'title' => $getMatchQuestion['question'],
                   'newCoinBalance' => $coin
                ];
        DB::commit();
        return response()->json($data);
      }catch(Exception $e){
        DB::rollBack();
        return return response()->json(['error' => $e->getMessage()]);
      }
    }
    
    var n = 5;
    
    function match_timer