Ajax 调用使用 IProgress 获取进度

问题描述 投票:0回答:1

我有 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;
    }
}
javascript c# .net ajax progress
1个回答
1
投票

为每个请求创建一个新的控制器,因此有两个不同的

_generateRecipeCardsStatus
变量。

如果您只想支持单个服务器上的单个调用,则可以将变量设置为静态。

如果您想允许多次调用,那么您将需要某种标识符/查找机制。请注意,您还需要一种在状态太旧(并且可能不再需要)时删除状态的方法,因此此查找更像是缓存而不是字典。

如果您想将其部署到多个服务器,那么您将需要一个外部缓存,而不是将其保存在内存中。

© www.soinside.com 2019 - 2024. All rights reserved.