我有 2 个 ajax API 调用,一个在长进程中获取数据,另一个使用 IProgress 接口获取进度值并每 5 秒执行一次。当点击调试器时,我可以看到
ReportProgress
中的值更新,并且该值被设置为 _generateRecipeCardsStatus
属性。我的问题是,当调用 getProgress()
-> GeneratePrintRecipeCardsStatus
时,属性 _generateRecipeCardsStatus
始终为零,我哪里出错了?
<script>
getData();
getProgress()
// long process
function getData() {
const token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
headers: {
'X-Requested-With': 'XMLHttpRequest',
"X-ANTI-FORGERY-TOKEN": token
},
type: 'POST',
url: `@Url.Action("GeneratePrintRecipeCards", "MenuPrintout")?id=` + @Model.RecipeCardLabelId + `&menuHeaderId=` + @Model.MenuHeaderId,
success: function(response){
console.log(response)
const { errorMsg, progressValue } = response
inProgressEle.hide();
close.show();
if (errorMsg) {
toast(errorMsg, "error")
}
else if (progressValue > 0) {
console.log("progress value:" + progressValue);
}
else{
expand.hide()
collapse.hide()
statusEle.text("Ready");
completedEle.fadeIn()
}
}
});
}
// get progress
function getProgress() {
setInterval(function(){
$.ajax({
url: '@Url.Action("GeneratePrintRecipeCardsStatus", "MenuPrintout")',
type: "GET",
success: function (response) {
console.log(response)
$('#lblStatus').text(response)
}
})
}, 5000)
}
</script>
// controller
public class MenuPrintoutController : BaseController
{
private readonly IMenuLabelService _menuLabelService;
private int _generateRecipeCardsStatus;
private Progress<int> _progress;
public MenuPrintoutController(IMenuLabelService menuLabelServicee)
{
_menuLabelService = menuLabelService;
}
// Is always zero
public int GeneratePrintRecipeCardsStatus()
{
return _generateRecipeCardsStatus;
}
// Updates fine
private void ReportProgress(int progress)
{
_generateRecipeCardsStatus = progress;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> GeneratePrintRecipeCards(int id, int menuHeaderId)
{
try
{
_progress = new Progress<int>(ReportProgress);
var data = await _menuLabelService.DoAsync(int menuHeaderId, _progress);
TempData.Put("PrintRecipeCards", data);
return Json(new { Success = true });
}
catch (Exception exp)
{
return Json(new { ErrorMsg = exp.Message });
}
}
}
// service
public interface IMenuLabelService
{
Task<object> DoAsync(int menuHeaderId, IProgress<int> progress);
}
public class MenuLabelService : IMenuLabelService
{
public async Task<object> DoAsync(int menuHeaderId, IProgress<int> progress)
{
var menuFoodItemsList = _context.FoodItemUnits
.Where(x => x.MenuSectionFoodItemUnits.Any(y => y.Menusection.MenuheaderId == menuHeaderId))
.Select(x => x.Fooditem)
.ToList();
var menuFoodItems = new List<PrintLabel>();
var donePointer = 0;
foreach (var menuFoodItem in menuFoodItemsList)
{
menuFoodItems.Add(menuFoodItem);
// ...
progress.Report((int)(++donePointer / (double)menuFoodItemsList.Count * 100));
donePointer++;
}
return menuFoodItems;
}
}
为每个请求创建一个新的控制器,因此有两个不同的
_generateRecipeCardsStatus
变量。
如果您只想支持单个服务器上的单个调用,则可以将变量设置为静态。
如果您想允许多次调用,那么您将需要某种标识符/查找机制。请注意,您还需要一种在状态太旧(并且可能不再需要)时删除状态的方法,因此此查找更像是缓存而不是字典。
如果您想将其部署到多个服务器,那么您将需要一个外部缓存,而不是将其保存在内存中。