无法让 JQuery Ajax 在 DNN 上真正异步运行,如果你点击一个链接,它会等待服务器先带回数据然后重定向

问题描述

我有一个 DNN 模块,可以使用 Lightslider 构建产品轮播。

页面加载时,从我们的 ERP 服务器数据库获取 10 个产品需要几秒钟的时间。 在加载时,当我尝试导航到另一个页面时,它不会重定向,直到 Ajax 查询返回数据。它将等到产品加载完毕,然后重定向到我大约 5 秒前点击的链接

我已启用 async: true 并尝试将 async 添加到服务器端代码,但没有成功。

$(document).ready(function () {
        GetCarouselProductData();
});


async function GetCarouselProductData() {
    var CarouselModID = "<%=CarouselModID%>";
    var CarouselMode = "<%=CarouselMode%>";
    var CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/PRandomProductCarousel/API/RandomProductCarousel/GetRandomCarouselProductssqlAsync?ModID=' + CarouselModID;
    if (CarouselMode == 'SpecificSKU') {
        CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/PRandomProductCarousel/API/RandomProductCarousel/GetSpecificSKUCarouselProductsAsync?ModID=' + CarouselModID;
    }

    await $.ajax({
        type: "GET",contentType: "application/json; charset=utf-8",cache: false,url: CarouselURL,datatype: "json",async: true,success: function (data) {
            var counter = 0;
            var VatText = "<%=IncTaxText%>";
            var DetailedLinkRedirect = "<%=DetailedPageLink%>/sku/";
            

            if (data.length > 0) {
                var source = "";

                $.map(data,function (item) {
                    var ImageSRC;
                    if (item.Productimages.length > 0) {
                        ImageSRC = item.Productimages[0].ProductThumbUrl
                    } else {
                        ImageSRC = '/DesktopModules/RandomProductCarousel/Images/no_image.png';
                    }
              
                    var alphabet = (counter + 10).toString(36);
                    var TitleDescription = item.Title;

                    if (TitleDescription.length > 70) {
                        var NewTitle = TitleDescription.substr(0,70);
                        NewTitle = NewTitle.substr(0,NewTitle.lastIndexOf(" ")) + '...';
                    } else {
                        var NewTitle = TitleDescription;
                    }

                    var StockCode = item.StockCode.trim();
                    var FinalRedirectLink = DetailedLinkRedirect + StockCode;

                    source += "<li class=\"item-" + alphabet +"\">"+
                        "<div class='Box'>"+
                        "<!--image Box-------->"+
                          "<div class='slide-img'>"+
                        "<img src='" + ImageSRC + "' alt='" + item.Title + "' />"+
                            "<!--overlay-->"+
                                "<div class='overlay-carousel'>"+
                        "<!--buy btn---->" +
                            "<div class='overlay-inner-carousel-btn-positioning'><a href='javascript:void(0);' class='carousel-quote-btn' onclick=\"addQuoteWithOnClickFunction('" + item.StockCode + "',1,'" + item.CustomerPriceInclVat + "');\">Add to Quotes</a></div>" +
                        "<div class='overlay-inner-carousel-btn-positioning'><a href='javascript:void(0);' class='carousel-buy-btn' onclick=\"addProductWithOnClickFunction('" + item.StockCode + "','" + item.CustomerPriceInclVat + "');\"><%=CartButtonText%> </a></div>" +
                        "<div class='overlay-inner-carousel-btn-positioning'>" +
                            "<a href='" + FinalRedirectLink + "' class='carousel-view-btn'>View</a>" +
                        "</div>" +
                            "</div>"+
                        "</div>"+
                        "<!--Detail Box-->"+
                            "<div class='detail-Box'>"+
                                "<!--type-->"+
                                "<div class='type'>"+
                                    "<a href='" + DetailedLinkRedirect + item.StockCode + "'>" + NewTitle +"</a>"+                                      
                                "</div>"+
                                "<!--price-->" +
                                "<div class='CarouselStockCode'>" +
                                    "<span class='carousel-stock'>" + StockCode + "</span>" +                                   
                                "</div>" +
                                "<span class='price'>" + item.CustomerPriceInclVat + " " + VatText + "</span>" +
                              "</div>"+
                            "</div>"+
                        "</li>";

                    counter++;
                    return source;

                });
                $("#autoWidth2").remove();
                $(".lSSlideOuter").remove();
                $(".responsive-product-carousel").remove();
                $(".responsive-product-carousel2").append(source);
            }
        },error: function (xhr,ajaxOptions,thrownError) {
            $.fancybox.open(xhr.responseText);
        }
    }).promise().done(function () {
        $(document).ready(function () {
            //ZR - 29/01/2021 - Mode that determines if it should auto slide
            var SliderMode = "<%=AutoSlideSetting%>";
            if (SliderMode == "False") {
                SliderMode = false;
            } else {
                SliderMode = true;
            }
            //ZR - 29/01/2021 - Sets the loop mode of the slider
            var LoopMode = "<%=LoopSliderSetting%>";
            if (LoopMode == "False") {
                LoopMode = false;
            } else {
                LoopMode = true;
            }
            var SliderPauseTime = <%=SliderPausePeriod%>;
            // website for settings sachinchoolur.github.io/lightslider/settings.html
            $('#autoWidth').lightSlider({                  
                autoWidth: true,loop: LoopMode,adaptiveHeight: true,pauSEOnHover: true,auto: SliderMode,pause: SliderPauseTime,onSliderLoad: function () {
                    $('#autoWidth').removeClass('cS-hidden');
                }
            });

            ViewCarouselProductLoading();
        });
    });

在Controller的服务器端,我尝试使用以下两种方式来获取数据,但似乎没什么区别。

没有异步代码的控制器代码(测试 1):

        /// <summary>
        /// Get Random Product information via sql
        /// </summary>
        /// <returns></returns>
        /// <remarks>ZR 25/01/2021</remarks>
        [AllowAnonymous]
        [HttpGet]
        public object GetRandomCarouselProductssqlAsync(int ModID)
        {
            try
            {
                AmountOfRandomProductsToFetch = TryGetPortalSetting("AmountOfRandomProductsToLoad_" + ModID);
                return GetRandomProductsFromsql(Int32.Parse(AmountOfRandomProductsToFetch));
            }
            catch (Exception ex)
            {
                EventLogController logController = new EventLogController();
                logController.AddLog("Could not retreive random products for the Product Carousel via sql.",ex.ToString(),EventLogController.EventLogType.ADMIN_ALERT);
                throw;
            }
        }

带有异步代码的控制器代码(测试 2):

        /// <summary>
        /// Get Random Product information via sql
        /// </summary>
        /// <returns></returns>
        /// <remarks>ZR 25/01/2021</remarks>
        [AllowAnonymous]
        [HttpGet]
        public async System.Threading.Tasks.Task<object> GetRandomCarouselProductssqlAsync(int ModID)
        {
            try
            {
                return await GetRandomProductssqlAsync(ModID);
            }
            catch (Exception ex)
            {
                EventLogController logController = new EventLogController();
                logController.AddLog("Could not retreive random products for the Product Carousel via sql.",EventLogController.EventLogType.ADMIN_ALERT);
                throw;
            }
        }

        public async System.Threading.Tasks.Task<object> GetRandomProductssqlAsync(int ModID)
        {
            try
            {
                AmountOfRandomProductsToFetch = TryGetPortalSetting("AmountOfRandomProductsToLoad_" + ModID);                
                return GetRandomProductsFromsql(Int32.Parse(AmountOfRandomProductsToFetch));
            }
            catch (Exception ex)
            {
                EventLogController logController = new EventLogController();
                logController.AddLog("Could not retreive random products for the Product Carousel via sql.",EventLogController.EventLogType.ADMIN_ALERT);
                throw;
            }

        }

我什至尝试使用“Then”以不同方式执行 Ajax 调用,但没有成功。

$(window).load(function () {       
    console.log("window is loaded");
    doAjaxGet()
        .then(json => {
            console.log('json: ',json);
            processjsONData(json);
    })
});

async function doAjaxGet() {
        var CarouselModID = "<%=CarouselModID%>";
        var CarouselMode = "<%=CarouselMode%>";
        var CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/PRandomProductCarousel/API/RandomProductCarousel/GetRandomCarouselProductssqlAsync?ModID=' + CarouselModID;
        if (CarouselMode == 'SpecificSKU') {
            CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/PRandomProductCarousel/API/RandomProductCarousel/GetSpecificSKUCarouselProductsAsync?ModID=' + CarouselModID;
        }
        const result = await $.ajax({
            url: CarouselURL,crossDomain: true,type: 'GET',});
        return result;
    }

function processjsONData(data) {
        // NOTE: data is already parsed
        $.map(data,function (item) {
            console.log('Data: ',item.Title);
        });
}

更新

我已将前端代码更改为使用普通的 XMLHttpRequest 而不是 JQuery Ajax。我在下面有两个视频来展示它到底在做什么以及下面的 Javascript Ajax 代码

视频 1(构建产品轮播)
https://www.youtube.com/watch?v=n637FGv3e9U

视频 2(仅将产品标题记录到控制台日志)
https://www.youtube.com/watch?v=8mHNcgBoe-Q

Javascript Ajax 代码

$(document).ready(function () {     
   JavascriptCarouselFetch();
});

function JavascriptCarouselFetch() {
    var CarouselModID = "<%=CarouselModID%>";
    var CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/ParrotRandomProductCarousel/API/RandomProductCarousel/GetRandomCarouselProductssqlAsync?ModID=' + CarouselModID;

    var http = new XMLHttpRequest();
    http.open("GET",CarouselURL,true);
    http.send();

    http.onreadystatechange = function () {
        if (http.readyState == 4 && http.status == 200) {

            $.map(JSON.parse(http.response),function (item) {
                console.log("Data: " + item.Title);
            })
        }
    };

控制器代码

/// <summary>
/// Get Random Product information via sql
/// </summary>
/// <returns></returns>
/// <remarks>ZR 25/01/2021</remarks>
[AllowAnonymous]
[HttpGet]       
  public async System.Threading.Tasks.Task<object> GetRandomCarouselProductssqlAsync(int ModID)
    {
        try
        {               
            AmountOfRandomProductsToFetch = TryGetPortalSetting("AmountOfRandomProductsToLoad_" + ModID);
            return GetRandomProductsFromsql(Int32.Parse(AmountOfRandomProductsToFetch));
        }
        catch (Exception ex)
        {
            EventLogController logController = new EventLogController();
            logController.AddLog("Could not retreive random products for the Product Carousel via sql.",EventLogController.EventLogType.ADMIN_ALERT);
            throw;
        }
    }

 /// <summary>
 /// Gets Random Products from sql
 /// </summary>
 /// <param name="ProdCode"></param>
 /// ZR 25/01/2021</remarks>
    public object GetRandomProductsFromsql(int AmountOfRandomProductsToFetch)
    {
        try
        {
            if (AmountOfRandomProductsToFetch > 0)
            {

                int pid = PortalController.Instance.GetCurrentPortalSettings().PortalId;
                if (SessionManager.GSettings == null) SessionManager.GSettings = new ParrotDNNCommon.Components.GlobalSettings(pid);

                var portalCtrl = new ParrotDNNCommon.Controllers.ParrotPortalSettingsController();
                var parrotPortalController = new ParrotPortalSettingsController();
                var currSettings = parrotPortalController.GetPortalSettings(pid);

                return m_Product.GetRandomProductWebDetailsFromsql(SessionManager.GSettings.Globalvars,pid,AmountOfRandomProductsToFetch,currSettings.PricingModeIsShowRRPOnly);

            }
            return null;
        }
        catch (Exception exc)
        {
            throw;
        }
    }

公共类

/// <summary>
        /// Get the product details
        /// </summary>
        /// <param name="GV">Global Variables</param>
        /// <param name="WebPortalId">Web Portal ID</param>
        /// <param name="Count">Amount of random products to return</param>
        /// <param name="ShowRRPOnly">Boolean to determine if RRP should only show or not</param>
        /// <returns>WebProductDetails</returns>
        /// <remarks>ZR - 25/01/2021</remarks>
        public List<CommonDataDeFinitions.Products.WebProductDetails> GetRandomProductWebDetailsFromsql(CommonLibrary.Globalvars GV,int WebPortalId,int Count,bool ShowRRPOnly)
        {
            List<CommonDataDeFinitions.Products.WebProductDetails>  result = new List<CommonDataDeFinitions.Products.WebProductDetails>();

            try
            {
                result = GV.ClHelper.eBusiness.GetRandomProductWebDetails(WebPortalId,SessionManager.CurrentUserInfo.CustomerCode,ShowRRPOnly,Count,SessionManager.CurrentUserInfo.ParrotUserId);                                                      
            }
            catch (Exception ex)
            {
                EventLog.LogEvent("GetProductWebDetails","There was an error retrieving the product details. " + ex.Message,DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT);
            }

            return result;
        }

ERP 代码

        ''' <summary>
        ''' Gets a Random Collection of <see cref="WebProductDetails"/> and pricing for the website.
        ''' </summary>
        ''' <param name="WebPortalId"><see cref="Integer"/>: Target Web Portal Id.</param>
        ''' <param name="CustomerCode"><see cref="String"/>: Customer Code.</param>
        ''' <param name="ShowRRPOnly"><see cref="Boolean"/>: Show RRP Only.</param>
        ''' <param name="ProductCount"><see cref="Integer"/>: Count of Products to Return.</param>
        ''' <param name="WebUserId"><see cref="Integer"/>: Web User Id.</param>
        ''' <returns><see cref="List(Of WebProductDetails)"/></returns>
        ''' <remarks>KeS/ZR 25/01/2021: created.</remarks>
        Friend Function GetRandomProductWebDetails(WebPortalId As Integer,CustomerCode As String,ShowRRPOnly As Boolean,ProductCount As Integer,WebUserId As Integer) As List(Of WebProductDetails)
            Dim Result As List(Of WebProductDetails) = GetRandomProductDetailsForWeb(WebPortalId,CustomerCode,ProductCount,WebUserId)
            Return Result
        End Function

        ''' <summary>
        ''' Gets a Random Collection of <see cref="WebProductDetails"/> and pricing for the website.
        ''' </summary>
        ''' <param name="WebPortalId"><see cref="Integer"/>: Target Web Portal Id.</param>
        ''' <param name="CustomerCode"><see cref="String"/>: Customer Code.</param>
        ''' <param name="ShowRRPOnly"><see cref="Boolean"/>: Show RRP Only.</param>
        ''' <param name="ProductCount"><see cref="Integer"/>: Count of Products to Return.</param>
        ''' <param name="WebUserId"><see cref="Integer"/>: Web User Id.</param>
        ''' <returns><see cref="List(Of WebProductDetails)"/></returns>
        ''' <remarks>KeS/ZR 25/01/2021: created.</remarks>
        Friend Function GetRandomProductDetailsForWeb(WebPortalId As Integer,WebUserId As Integer) As List(Of WebProductDetails)
            Dim result As List(Of WebProductDetails) = New List(Of WebProductDetails)
            Try
                result = dao.FinishedGoods.GetRandomWebProductDetailsByCount(ProductCount)
                If result.IsNullOrEmpty() Then Return New List(Of WebProductDetails)

                'User Id < 0 is not logged in,recommended price will always be fetched
                Dim canWebUserViewCustomerPrice As Boolean = If(WebUserId <= 0,True,CheckIfUserHasWebRight(UserRights.WebUserCanViewStockItemPrices,WebUserId))
                'override the User Right if DNN site set to always show recommended price no matter what
                If (ShowRRPOnly) Then canWebUserViewCustomerPrice = False

                For Each product In result
                    'Get the customer pricing,DS 21/06/2017 - fixed to get correct Web channel default ID,Now uses default obj for this
                    Dim priceCalc As StockItemPricingForCustomer = blHelper.Fingoods.GetStockItemPricingForCustomer(DefaultStockItemPricingForwebargs(product.StockCode,Not canWebUserViewCustomerPrice,dao.Customers.SelectCustomerDealerType(CustomerCode)))
                    'RB 2017-07-11: Get the Kit Items for the product
                    Dim CodeList As IList(Of String)
                    CodeList = New List(Of String)
                    CodeList.Add(product.StockCode)
                    Dim relatedProducts As List(Of RelatedProduct) = dao.DaoPortal.SelectKitItems(CodeList)
                    product.KitItems = relatedProducts

                    product.ShowStockAvailable = blHelper.SystemRules.WebShowStockAvailability()
                    product.NoStockAvailableMessage = blHelper.SystemRules.WebNoStockAvailableMessage()

                    product.RetailPriceExVat = priceCalc.RetailPrice
                    product.Customerdiscount = priceCalc.Customerdiscount
                    product.CustomerPriceExVat = priceCalc.CustomerPrice
                    product.CustomerPriceInclVat = priceCalc.PriceWithTax

                    product.ExtraInfo = dao.FinishedGoods.SelectDetailedDescriptionForStockCode(product.StockCode).DescriptionHTML
                    product.DownloadLinksHTML = blHelper.Fingoods.GenerateProductDownloadLinksHTML(String.Empty,product.StockCode,"line-height:20px;text-align:left;",GetCompanyIdFromDatabaseName(dao.dbname,WebPortalId))
                    product.Productimages = blHelper.Fingoods.GetProdcutimageLinksOnly(String.Empty,WebPortalId))

                    ' RB 2017-10-11: Lifestyle data for the product StockParent_MetaData
                    Dim MetaData As StockParent_MetaData = dao.Productvariations.SelectMetaData(product.StockID)
                    product.ShowWebInfoButton = MetaData.ShowAdditionalWebInfo
                    product.WebInfoURL = MetaData.AdditionalWebInfoURL
                    product.WebInfoTarget = MetaData.AdditionalWebInfoTargetdisplay
                    product.WebInfoButtonText = MetaData.AdditionalWebInfoButtonText
                    ' Rest of MetaData can also be returned here


                        'DS 21/01/2019 - Fetch Individual Warehouse Stock Levels and set the new property (following the business rule for showing stock)    
                        If product.ShowStockAvailable Then product.WarehouseStockLevels = LLDataUtils.ConvertDataTabletoObjectListUsingIMapFromDataTableInterface(Of PortalWarehouseStockLevel)(dao.DaoPortal.SelectWarehouseStockLevelsForPortal(New String() {product.StockCode},nothing))
                        product.ItemsInStock = If(product.ShowStockAvailable,product.WarehouseStockLevels.Sum(Function(w) w.Amount),-1)
                    Next
    
                Catch ex As Exception
                    CommonServer.ErrorHandler.ServerError(ex,"An error occurred attempting to retrieve a Random Assortment of Products for the Website",ExceptionTypes.UndefinedException,True)
                End Try
                Return result
            End Function

        ''' <summary>
        ''' Get Random product details for the web for the provided count of items.
        ''' </summary>
        ''' <returns>WebProductDetails</returns>
        ''' <remarks>KeS/ZR 25/01/2021: created.</remarks>
        Friend Function GetRandomWebProductDetailsByCount(Count As Integer) As List(Of WebProductDetails)
            Dim sql As New StringBuilder

            With sql
                .AppendLine($" SELECT TOP {Count} SP.Id 'StockID',SP.StockCode 'StockCode',ISNULL(SP.FriendlyTitle,FG.Description) 'Title','' as 'Description',FG.DetailedDescription 'ExtraInfo',")
                .AppendLine("        SP.SlugURL 'SlugURL',ISNULL(SP.MetaTitle,FG.Description)) 'MetaTitle',SP.MetaDescription 'MetaDesc',SP.MetaKeywords 'MetaKeywords',SP.MainProductimageTitle 'MainImageTitle',sp.MainProductimageDescription 'MainImageDesc',fg.BarCode,fg.PrimaryPublishingCategories_ID AS PrimaryPublishingCategoryID,")
                .AppendLine("        FG.Price 'RetailPriceExVat',COUNT(ISNULL(W.QUANTITY,0)) 'ItemsInStock',PC.Name AS PrimaryPublishingCategoryName ")
                .AppendLine("   FROM StockParent SP ")
                .AppendLine("  INNER JOIN Fingoods FG ON FG.Id = SP.Id AND FG.IsDeleted = 0 AND FG.Publish = 1")
                .AppendLine("  LEFT JOIN WAREHOUSESTOCK W ON w.FinGoods_ID = SP.Id ")
                .AppendLine(" LEFT JOIN PublishingCategories AS PC ON PC.ID = FG.PrimaryPublishingCategories_ID AND PC.IsDeleted = 0 ")
                .AppendLine("  WHERE SP.IsDeleted = 0 ")
                .AppendLine("  GROUP BY SP.Id,SP.StockCode,FG.Description),FG.DetailedDescription,SP.SlugURL,FG.Description)),SP.MetaDescription,SP.MetaKeywords,SP.MainProductimageTitle,sp.MainProductimageDescription,FG.Price,fg.PrimaryPublishingCategories_ID,PC.Name")
                .AppendLine("  ORDER BY NEWID() ")
            End With

            Using cmd As sqlCommandHelper = GetCommand(sql.ToString)
                Return cmd.ExecuteList(Of WebProductDetails)
            End Using
        End Function

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...