9

我有长时间运行的任务,使用 jquery ajax 调用。我正在使用块 ui 插件来显示“正在加载”。无论如何我可以将进度消息发送回客户端以显示进度并在块 ui 插件消息上更新。

所以它会显示这个(当服务器完成它的工作时)。.

“正在加载第一个源……”
“正在加载第二个源……”
“正在加载第三个源……”
“解析结果……”

4

6 回答 6

11

从我所看到的上传东西的情况来看 - 人们创建一个单独的网关并查询它以获取进度信息,因为它仅在服务器端可用。但我认为在你的情况下这不是最好的事情。

如果您想加载带有进度信息的内容或允许服务器在生成输出时弹出进度信息,那么http 流就是您想要的。它在这里覆盖得很好。基本上它是一个单一的http请求,服务器以块的形式响应它一分钟左右(因此在它需要的时候发送东西),然后打开一个新的连接。

这对我来说是一个很大的发现;)

[编辑]

目前有很多更好的技术可用,所有这些都包含在Socket.IO - Websockets 中,可以回退到其他技术,包括http 流

Socket.IO 是 nodeJS 的一个模块,但还有其他类似的实现。我已经使用来自https://github.com/Atmosphere/atmosphere的 JAVA Socket.IO 实现交换了一些数据包

于 2010-05-08T18:25:00.740 回答
4

一种方法是将 HTTP 处理程序和 AJAX 与 jQuery 一起使用。

1.发起Server端请求

$("#btnCreateInvoice").click(function() {             
       $.ajax({ type: "POST",  url: "YourHttpHandler.ashx",
       contentType: "text/html; charset=utf-8",
       dataType: "html",  
       success: function(data) { start the block UI }
       });
    });

2. 投票

接下来您需要做的是以“t”间隔轮询服务器并获取状态。为此,我们需要以“t”间隔调用一个函数,该函数将启动对 HTTPHandler 的 AJAX 调用以获取状态。

$(function() {
  setInterval(updateStatus, 't');
});

function updateStatus() {
  $.ajax({ type: "POST",  url: "GetStatusHandler.ashx",
       contentType: "text/html; charset=utf-8",
       dataType: "html",  
       success: function(data) { process 'data' here and update the block UI message box }
       });
}

在您的情况下, GetStatusHandler.ashx 可以返回完整的 innerHtml 状态。例如,在第一次调用时它会返回'Loading First source...',然后它可能会返回:
Loding First source...
Loading Second source...
等等。

于 2010-05-19T05:49:36.090 回答
1

我会让每个 AJAX 请求返回一个 JSON 响应,其中包含一条消息、数据和下一个要请求的 URL:{message: "Loading second resource...", data: ..., next_url: "/next_part"}

在您的第一个 AJAX 请求之前,将 BlockUI 消息设置为“正在加载...”。当您收到响应时,将 BlockUI 消息设置为您从 AJAX 调用返回的消息。然后对“next_url”的值进行下一次 AJAX 调用,依此类推,循环直到完成所有任务。

如果您要加载一个大型数据集,但要分段加载,您可能想要执行渐进式加载设计模式之类的操作,但还要在收到每个响应时设置一个进度消息。

于 2010-05-18T20:12:43.047 回答
1

我最近才意识到一个执行 ajax “推送”的项目。您可能想检查一下:

http://www.ape-project.org/

据我所知,还有一些其他项目在做类似的事情,这是最真实的:“将进度消息发送回客户端”,其中另一个解决方案需要请求轮询进度(仍然是一个非常合法和好的解决方案)。

于 2010-05-08T18:29:33.157 回答
0

好吧,我有类似的情况,我用另一种方法解决了它。这是一个非常丑陋的解决方法,我知道,所以请不要开始说它有多糟糕,因为我知道,但它可以满足我的需要。

我将进度放在服务器端的文件中。例如,我调用了 process.php,它需要做很多工作,并且需要一段时间才能完成,所以用户很紧张,他关闭了浏览器(不太好)。所以 process.php 正在将一些输出保存到服务器上的文件中。在调用 process.php 的页面上,我有一个小 div、span 或任何我想显示进度的地方,但我建议使用 div。每 X 毫秒或秒,我从 div 中的服务器加载另一个脚本,假设 display_info.php 现在 display_info.php 正在读取由 process.php 输出的文件,并且内容显示在 div 中。

您必须注意 process.php 的输出对于每个场合都必须是唯一的,否则您会将信息输出到浏览器中。

埃米尔

于 2013-09-15T18:54:54.387 回答
0

您正在尝试做的是类似于Comet的事情。传统(“非彗星”)网络服务器不是为这种交易模型设计的,因此不是理想的解决方案。

我的建议是将每个数据源的处理分解为一个客户端请求:

function loadData() {
   // Each call passes callback(id) as a success handler
   fireAsynchronousRequest("source1");
   fireAsynchronousRequest("source2");
   fireAsynchronousRequest("source3");
}

function callback(var source) {
   if (source == "source1") {
       updateStatus("Source 1 loaded");
   }
   else if (source == "source2") {
       updateStatus("Source 2 loaded");
   }
}

这是一个异步解决方案的示例。callback()如果需要同步,您可以实现状态处理 。

于 2010-05-19T07:42:25.230 回答