我已经尝试了各种方法来寻找解决方案,但我似乎找不到合适的单词组合或其他东西…是:
我有ASP。NET MVC应用程序,用户扫描库存/包装条形码。每次有人扫描一件商品时,我都会发出一个异步请求,然后显示一个弹出消息,其中包含有关该商品的信息。这部分按预期工作,并且在请求期间不会阻塞应用程序:
$.ajax({
type: 'GET',
dataType: 'json',
async: false,
url: '@Url.Action("SingleOrderLookup")?trackingNumber=' + trackingId,
success: function (result) {
if (result.success) {
var audio = findAudio(result.model, audioClips, saturdayAudio);
suppressDefaultSound = true;
var titleText = result.model.displayPromptText;
if (result.model.isRefrigerated) {
isRefrigerated = true;
titleText = "<p style='color: blue;'>(REFRIGERATED)</p>" + "<p>" + result.model.displayPromptText + "</p>";
}
swal.fire({
title: titleText,
text: "Place in route for " + result.model.displayPromptText,
type: "success",
showCancelButton: false,
confirmButtonText: "Sorted",
cancelButtonText: "Cancel",
timer: 1750,
preConfirm: function () {
return new Promise(function (resolve) {
resolve();
}, 1000);
}
}).then(result => {
if (result.value) {
}
});
var dupe = findOrderByTrackingNumber(trkNumbers, result.model.trackingId);
if (!dupe) {
trkNumbers.push({ trackingNumber: trackingId, depotId: result.model.destinationHub });
pkgCount++;
if ($("#divUpdatePickup").is(":hidden"))
$("#divUpdatePickup").show();
AddLogToTable(trackingId);
} else {
//audible feedback that duplicate was scanned
//if (!trkBin) PlayAudio(2);
//PlayAudio(2);
}
//playing audio
if (isRefrigerated) {
setTimeout(function () {
if (audio) playByteArray(audio);
}, 1500);
PlayRefrigerate();
} else {
if (audio) playByteArray(audio);
}
}
if (result.nullRoute) {
addToTrkNumbers = false;
Swal.fire({
title: "NO ROUTE DEFINED",
text: "Unable to match order to a route!",
type: "warning",
showCancelButton: false
});
}
}
});
然而,我希望页面进行另一个异步调用,用对象数组填充变量,透明且不阻止用户从上述代码的异步调用中进行扫描和接收信息。这个调用应该在加载页面时立即发生,并且可能需要一两分钟以上的时间来接收这个调用所期望的所有数据。响应返回后,应该填充集合变量(zipSort[])。此变量中的数据将包含一个"缓存"。的元素,以避免在每次扫描后进行单独的服务器端调用(实际上,我想要"预先加载")。扫描事件所需的数据,一旦完成,就不需要对服务器进行单独的调用,因为该变量应该包含预期要扫描的99%的id)。
这就是我遇到问题的地方,这可能是由于缺乏对异步调用/JS承诺如何工作的理解。下面是我到目前为止编写的代码:
//array to hold data on expected tracking number scans
var zipSort = []
async function getCheckinGroup(zipSort) {
console.log("Fetching complete check-in group...");
var url = '/SortFacility/HubManager/GetOrders';
var promise = new Promise((resolve,reject) => {
$.ajax({
type: "GET",
url: url,
cache: false,
async: true,
contentType: "application/json",
success: function (result) {
if (result.success) {
console.log("Retrieval success");
try {
zipSort = result.model;
resolve(result.model);
} catch (ex) {
reject("Some error?");
}
} else {
reject("Some error?");
}
},
error: function (ob, errStr) {
reject("Something went wrong");
}
});
});
return promise;
}
//don't want this to hold up execution of the rest of the code, so zipSort[] should
//remain empty and get set transparently when the ajax response is returned:
getCheckinGroup(zipSort);
从我读过的文章和教程中试用的每个版本的代码都会阻塞UI,使用户无法在未返回响应时扫描项目。我错过了什么?我应该如何改变这一点,以便(a)用户可以在页面加载完毕后立即开始扫描,并从对数据库的各个异步调用中接收信息,(b) zipSort[]可以填充这些扫描可能需要的所有数据,一旦填充,扫描事件触发对该变量的查找,而不是继续对数据库的单独调用?
任何帮助将不胜感激!
编辑:尝试简单地添加这个调用内联,无论我把它放在哪里,它阻止其他代码运行,直到收到响应,即使async设置为true:
$.ajax({
type: "GET",
url: url,
cache: false,
async: true,
contentType: "application/json",
success: function (result) {
console.log("Data received.");
zipSort = result.model;
}
});
感谢大家的帮助。我找到了这个小宝贝,它解决了我的问题:
https://josef.codes/c-sharp-mvc-concurrent-ajax-calls-blocks-server/
应用[SessionState(System.Web.SessionState.SessionStateBehavior.Disabled)]到我的控制器类启用并发异步ajax调用