Javascript等待ajax成功后再执行代码

Javascript wait for ajax success before code execution

本文关键字:执行 代码 成功 等待 ajax Javascript      更新时间:2023-09-26

我正试图在我的网页上实现以下场景:

  1. 用户访问页面(请注意,用户具有唯一的ID)
  2. 用户必须执行任务,然后按下next按钮
  3. 当按下按钮时,我会在数据库中查找它是否是用户的第一次访问
  4. 如果是的话,他必须等60秒才能按下按钮,所以我提醒他

我检查了类似同步问题的解决方案:

  • 如何等待ajax成功处理程序完成后再执行另一个
  • 在使用jQuery运行代码之前等待AJAX调用
  • JavaScript同步选项

但无法使它们真正适应我的情况。

每次用户按下next按钮时,都会执行以下代码段。

    // get timing for instruction reading
    var currentTime = new Date().getTime();
    totalTime = currentTime - startTime;
    console.debug("Time: " + totalTime);
    if (flag_instructions_pressed == false){
        $.ajax({
            url: "/IsNewUser/",
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify({
                "_user_id": _user_id,
            }),
            dataType: "text",
            success: function( returned_data ) {
                _user_exp = parseInt(returned_data);
                flag_instructions_pressed = true;
            }
        });
    }
    if ( totalTime < 60000 && _user_exp == 0) {
        alert("You have to wait 60 seconds");
        return;
    }
  • ajax请求将返回一个字符串,其中包含有问题的用户以前的访问次数,并且对于该会话应该只执行一次(因为它将用户添加到数据库中)。结果存储在全局变量_user_exp

我有以下问题:

即使用户多次访问该页面,由于if语句是在ajax请求的success函数之前执行的,因此仍会向他显示警报。

我该如何解决?

注意1:我不能简单地将if语句移动到success函数中,因为即使在flag_instructions_pressed设置为true之后,它仍然应该执行。flag_instructions_pressed只是在执行ajax请求之后被设置为true的初始化为false的标志。这样可以防止在第二次执行代码时再次发生请求。

注意2:显然,如果我在if语句之前发出警报(或只是超时),一切都会正常工作。但我认为这是一种糟糕的编程实践,我想学习如何处理这种类型的同步问题。

一个解决方案是使用promise。它们充当未来值的占位符,您可以多次"检查其未来值":

var newUserCheck;
function nextButtonHandler() {
    // get timing for instruction reading
    var currentTime = new Date().getTime();
    totalTime = currentTime - startTime;
    console.debug("Time: " + totalTime);
    if (!newUserCheck) {
        newUserCheck = $.ajax({
            url: "/IsNewUser/",
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify({
                "_user_id": _user_id,
            }),
            dataType: "text"
        }).then(function ( returned_data ) {
           _user_exp = parseInt(returned_data);
           return _user_exp;
        });
    }
    newUserCheck.then(function (user_exp) {
        if ( totalTime < 60000 && user_exp === 0 ) {
            alert("You have to wait 60 seconds");
            return;
        }
        // otherwise, complete the "next button procedure" here
    });
}

如何将if语句转换为函数:

function testTime() { 
  if ( totalTime < 60000 && _user_exp == 0) {
    alert("You have to wait 60 seconds");
    return;
  }
}

然后将另一个if语句转换为if/else,在else块(flag_instructions_pressed == true)和ajax调用的成功函数(flag_instructions_pressed == false)中调用此函数:

if (flag_instructions_pressed == false){
    $.ajax({
        url: "/IsNewUser/",
        type: "POST",
        contentType: "application/json",
        data: JSON.stringify({
            "_user_id": _user_id,
        }),
        dataType: "text",
        success: function( returned_data ) {
            _user_exp = parseInt(returned_data);
            flag_instructions_pressed = true;
            testTime();
        }
    });
} else {
  testTime();
}