如何禁用表单按钮,直到功能完全完成



所以脚本中的所有内容都能完美工作。然而,代码的这一部分有一个问题:

var min = 1;
while (min < 200) {
var max = min + 30;
scan(fruitID, min, max);
var min = max;
}

我想从这个循环中得到什么:

  1. 计算max
  2. 调用scan()函数
  3. 等待扫描中的ajax成功获取数据,并将其显示在屏幕上
  4. 计算min
  5. 重复循环

错误出现在步骤3中。它不等待ajax取回数据并进行处理,而是直接重复循环。如何让循环等待scan()函数完全完成。

$(document).ready(function() {
$('#submit').click(function(e){
e.preventDefault();
$("#submit").attr("disabled", true);
$("#submit").html("Verifying Username");
var fruitName = $("#fruit-name").val();
$.ajax({
type: "POST",
url: "verify-input.php",
dataType: "json",
data: {fruitName:fruitName},
success : function(data){
if (data.code == 200){
$("#submit").html("Running Scan");
var fruitID = data.fruitId;
//alert("Fruit ID: " + fruitID);
var min = 1;
while (min < 200) {
var max = min + 30;
scan(fruitID, min, max);
var min = max;
}
} else {
$("#submit").attr("disabled", false);
$("#submit").html("Submit");
$(".display-error").html("<ul>"+data.msg+"</ul>");
$(".display-error").css("display","block");
}
}
});
});
});
function scan(vFruitId, min, max) {
$.ajax({
type: "POST",
url: "scanner.php",
dataType: "json",
data: {vFruitId: vFruitId, min: min, max: max},
success : function(data){
data.forEach((item, idx) => {
$("#results").append(`
<div class="fruit-item" data-item="${idx}">
<div class="f-calories">calories: ${item.sweetness}</div>
<div class="f-sweetness">sweeteness: ${item.calories}</div>
<div class="f-bitterness">bitterness: ${item.bitterness}</div>
</div>
`);
})
}
});
}
<form>
<label for="fname">Fruit (only correct input is: banana)</label><br>
<input type="text" id="fruit-name" name="fruit" value="banana"><br>
<button type="submit" id="submit" value="Submit">Submit</button>
</form>
<div id="results">
</div>

注意:您的原始代码没有重新启用表单按钮,因此问题标题有点误导

解决方案是使用$.ajax返回的类似Promise的对象

下面的代码使用箭头符号,就像问题中一样,但不使用async/await,因此可以在问题中代码工作的任何地方使用

$(document).ready(function () {
$('#submit').click(function (e) {
e.preventDefault();
$("#submit").attr("disabled", true);
$("#submit").html("Verifying Username");
var fruitName = $("#fruit-name").val();
$.ajax({
type: "POST",
url: "verify-input.php",
dataType: "json",
data: {
fruitName: fruitName
},
success: function (data) { 
if (data.code == 200) {
$("#submit").html("Running Scan");
var fruitID = data.fruitId;
//alert("Fruit ID: " + fruitID);
function runscan(min) {
return scan(fruitID, min, min+30)
.then(() => {
min = min + 30;
if (min < 200) {
return runscan(min);
}
});
}
runscan(1)
.then(() => {
// all done here
});
} else {
$("#submit").attr("disabled", false);
$("#submit").html("Submit");
$(".display-error").html("<ul>" + data.msg + "</ul>");
$(".display-error").css("display", "block");
}
}
});
});
});
function scan(vFruitId, min, max) {
return $.ajax({
type: "POST",
url: "scanner.php",
dataType: "json",
data: {
vFruitId: vFruitId,
min: min,
max: max
},
success: function (data) {
data.forEach((item, idx) => {
$("#results").append(`
<div class="fruit-item" data-item="${idx}">
<div class="f-calories">calories: ${item.sweetness}</div>
<div class="f-sweetness">sweeteness: ${item.calories}</div>
<div class="f-bitterness">bitterness: ${item.bitterness}</div>
</div>
`);
})
}
});
}

或者,使用async/await,可以编写主success代码

success: function(data) {
if (data.code == 200) {
$("#submit").html("Running Scan");
(async function() { // `success` can't be async, because jquery doesn't like that
var fruitID = data.fruitId;
//alert("Fruit ID: " + fruitID);
var min = 1;
while (min < 200) {
await scan(fruitID, min, min + 30);
min = min + 30;
}
})();
} else {
$("#submit").attr("disabled", false);
$("#submit").html("Submit");
$(".display-error").html("<ul>" + data.msg + "</ul>");
$(".display-error").css("display", "block");
}
}

重要提示:根据第一个代码片段,您仍然必须在function scan中使用return $.ajax

最新更新