我正在尝试在我的网页上实现以下场景:
- 一个用户访问一个页面(注意用户有一个唯一的ID)
- 用户必须执行一个任务,然后按下
下一步
按钮 - 按下按钮时,我会在数据库中查找这是否是用户的第一次访问
- 如果是,他必须等待 60 秒才能按下按钮,以便我提醒他
我检查了类似同步问题的解决方案:
- How to wait for ajax success handler to finish before executing another
- Waiting for AJAX call before code runs using jQuery
- JavaScript synchronization options
但无法真正使它们适应我的情况。
每次用户按下 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
请求将返回一个字符串,其中包含有问题的用户之前的访问次数,它应该只在本次 session 中执行一次(因为它将用户添加到数据库中)。结果存储在全局变量_user_exp
中。
我有以下问题:
Even if a user has visited the page multiple times he will still be shown the alert since the
if
statement is executed before thesuccess
function from theajax
request.
如何解决?
注意 1: 我不能简单地将 if
语句移动到 success
函数中,因为即使在 flag_instructions_pressed
设置为 true
。 flag_instructions_pressed
只是一个初始化为 false
的标志,在执行 ajax
请求后被设置为 true
。这可以防止在第二次执行代码时再次发生请求。
注意 2: 显然,如果我在 if
语句之前放置一个警报(或只是一个超时),一切都会正常进行。但我认为这是不好的编程习惯,想学习如何处理此类同步问题。
最佳答案
对此的一种解决方案是使用 promise 。它们充当 future 值的占位符,您可以多次“检查它们的 future 值”:
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
});
}
关于Javascript 在代码执行前等待 ajax 成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29332847/