2

我有一个在服务器上调用长请求的网页。该请求会生成一个 Excel 文件,并在准备好后将其流式传输回客户端。

通过使用 jQuery 创建表单元素并调用提交方法来调用请求。

我想在处理请求期间向用户显示任务的进度。

我想使用 jQuery ajax 调用我在服务器上返回状态消息的服务来做到这一点。

我的问题是,当我调用此服务(使用 $.ajax)时,只有在表单提交发起的请求结束时才会调用回调。

有什么建议么 ?

编码:

 <script>
     function dummyFunction(){       
                var notificationContextId = "someid";

                var url = $fdbUI.config.baseUrl() + "/Promis/GenerateExcel.aspx";

                var $form = $('<form action="' + url + '" method="POST" target="_blank"></form>');
                var $hidden = $("<input type='hidden' name='viewModel'/>");
                $hidden.val(self.toJSON());
                $hidden.appendTo($form);

                var $contextId = new $("<input type='hidden' name='notifyContextId'/>").val(notificationContextId);
                $contextId.appendTo($form);

                $('body').append($form);

                self.progressMessages([]);

                $fdbUI.notificationHelper.getNotifications(notificationContextId, function (message) {
                    var messageText = '';
                    if (message.IsEnded) {
                        messageText = "Excel is ready to download";
                    } else if (message.IsError) {
                        messageText = "An error occured while preparing excel file. Please try again...";
                    } else {
                        messageText = message.NotifyData;
                    }

                    self.progressMessages.push(messageText);
                });
                $form.submit();
       }
<script>

该代码使用调用 $.ajax 的实用程序库。它的代码是:

(function () { if (!window.flowdbUI) { throw ("缺少对 flowdb.ui.core 的引用。"); }

function NotificationHelper() {
    var self = this;

    this.intervalId = null;

    this.getNotifications = function (contextId, fnCallback) {
        if ($.isFunction(fnCallback) == false)
            return;

        self.intervalId = setInterval(function() {
            self._startNotificationPolling(contextId, fnCallback);
        }, 500);

    };

    this._startNotificationPolling = function (contextId, fnCallback) {
        if (self._processing)
            return;

        self._processing = true;
        self._notificationPolling(contextId, function (result) {                
            if (result.success) {                    
                var message = result.retVal;
                if (message == null)
                    return;
                if (message.IsEnded || message.IsError) {
                    clearInterval(self.intervalId);
                }

                fnCallback(message);
            } else {
                clearInterval(self.intervalId);
                fnCallback({NotifyData:null, IsEnded:false, IsError:true});
            }
            self._processing = false;
        });
    };

    this._notificationPolling = function (contextId, fnCallback) {
        $fdbUI.core.executeAjax("NotificationProvider", { id: contextId }, function(result) {
            fnCallback(result);
        });
    };
    return this;
}

window.flowdbUI.notificationHelper = new NotificationHelper();
})();
4

1 回答 1

1

默认情况下,ASP.NET 将只允许每个会话一个并发请求,以避免竞争条件。因此,在长轮询请求完成之前,服务器不会响应您的状态请求。

一种可能的方法是让您的表单 post 立即返回,当状态请求显示完成时,启动一个新请求以获取它知道正在服务器上等待它的数据。

或者您可以尝试更改 EnableSessionState 设置以允许多个并发请求,如此所述。

于 2013-07-16T16:13:18.107 回答