问题描述
我已经尝试过寻找解决方案的方法,但我似乎无法找到正确的单词组合或其他东西...这里是:
我有一个 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",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 调用。