如何使用jQuery ajax请求web service并显示进度信息

net205 2010-09-11 05:01:10
我在开发中,有一个恢复网站的操作,比较耗时,我想在操作时往缓存中记录当前操作进度,然后另一个请求获取当前操作的进度即时显示在客户端显示。

问题:是另一个请求不能即时显示进度,而只是最后一次请求才可以改变进度条。

类似代码 WebService.ashx(c#):
public class WebService : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string invoke = string.Empty;
string jsoncallback = string.Empty;

if (!string.IsNullOrEmpty(context.Request["invoke"]))
invoke = context.Request["invoke"].ToString().Trim();
if (!string.IsNullOrEmpty(context.Request["jsoncallback"]))
jsoncallback = context.Request["jsoncallback"].ToString().Trim();

context.Response.ContentType = "application/x-javascript; charset=utf-8";
switch (invoke.ToLower())
{
case "call":
int currentValue = 0;
int TotalValue = 100;
HttpContext.Current.Cache.Remove("progress");
HttpContext.Current.Cache.Insert("progress", currentValue + "," + TotalValue, null,
DateTime.Now.AddMinutes(60),System.Web.Caching.Cache.NoSlidingExpiration);

for (int i = 1; i <= TotalValue; i++)
{
currentValue = i;
//TODO...
HttpContext.Current.Cache.Insert("progress", currentValue + "," + TotalValue, null,
DateTime.Now.AddMinutes(60), System.Web.Caching.Cache.NoSlidingExpiration);
Thread.Sleep(100);
}
context.Response.Write(string.Format("{0}({{error:{1}, message:\"{2}\"}})", jsoncallback, false.ToString().ToLower(), "finished."));
break;
case "progress":
string progress = "100,100";
if(HttpContext.Current.Cache["progress"] != null)
{
progress = HttpContext.Current.Cache["progress"].ToString();
}
context.Response.Write(string.Format("{0}({{error:{1}, message:\"{2}\"}})", jsoncallback, false.ToString().ToLower(), progress));
break;
default:
context.Response.Write(string.Format("{0}({{error:{1}, message:\"{2}\"}})", jsoncallback, false.ToString().ToLower(), "parameter error."));
break;
}
}

public bool IsReusable
{
get{return false;}
}
}


页面代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style>
.ProgressBar {
position:relative;
margin-top:30px;
margin-bottom:20px;
margin-left:240px;
width: 220px;
border: 1px solid #B1B1B1;
overflow: hidden;
}
.ProgressBar div {
position:relative;
background: #2BD029;
color: #333333;
height: 15px;
line-height: 15px;
text-align:left;
}
.ProgressBar div span {
position:absolute;
width: 220px;
text-align: center;
font-weight: bold;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
var intervalID;

function RequestProcess(){
$.getJSON("http://localhost:4397/webservice.ashx?invoke=progress&jsoncallback=?", function(data) {
var progress = data.message;
var position = parseInt(progress.split(",")[0] / progress.split(",")[1] * 100);
if(isNaN(position))
position = 0;
$('#divMessage').append("<br/>"+position);
if (position >= 100) stopRequestProcess();
$('.ProgressBar > div').css({ "width": position + "%" });
$('.ProgressBar > div > span').html(position + "%");
$('#ProgressInfo').html(position >= 100 ? "finished" : position);
});
}
function stopRequestProcess(){
clearInterval(intervalID);
}

$(document).ready(function(){
$('#btnStart').click(function(){
$('#divMessage').html('');
$.ajax({
type: "GET",
url: "http://localhost:4397/webservice.ashx?invoke=call&jsoncallback=?",
dataType: "jsonp",
async: false,
error: function(xhr, ajaxOptions, thrownError) {
stopRequestProcess();
},
success: function(response) {
stopRequestProcess();
$('.ProgressBar > div').css({ "width": "100%" });
$('.ProgressBar > div > span').html("100%");
$('#ProgressInfo').html("finished");
}
});

intervalID = setInterval(RequestProcess, 500);
});
});
</script>
</head>

<body>
<div>
<div>
<div class="ProgressBar" style="*margin-left:0px" align="left">
<div style="width:0%;*margin-left:0px"><span>0%</span></div>
</div>
<div id="ProgressInfo" class="ProgressInfo">processing...</div>
</div>
<button id="btnStart" name="btnStart">start</button>
</div>
<br/>Progress Information:<br/>
<div id="divMessage"></div>
</body>
</html>

...全文
830 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
net205 2010-09-30
  • 打赏
  • 举报
回复
不太满意结帖
net205 2010-09-28
  • 打赏
  • 举报
回复
歇几天再结账,听听意见
net205 2010-09-28
  • 打赏
  • 举报
回复
好多天没来了,感谢大家的关注。
刚才在家里电脑试了一下,我上面的代码在IE6、360浏览器(传说是IE7内核),Chrome都正常,符合我的要求,而在Firefox不行。

to IBM_hoojo:
我的代码是符合你要求的。只是backup工作没有用独立线程处理,最重要的是backup操作要马上返回结果,用线程进行后续处理。

to theforever:
你说的是错的,我以前用过async: true,也一样效果。 我想的是备份操作要马上返回结果,后续操作用其他方式继续进行(如线程处理)

to daxuejianku:
谢谢你的提议,抽空我学习一下,不过你给的这个对我应该是没用。


谢谢大家关注。 我想stackoverflow上面Darin Dimitrov提到的是最好解决办法,我把他的代码修改用jsonp形式,在IE6、360浏览器(传说是IE7内核)、Chrome、Firefox都满足我的要求。
北京不不 2010-09-14
  • 打赏
  • 举报
回复
你可以玩玩日本人写的javascript多线程库
Concurrent.Thread.js
zhangshaolongjj 2010-09-14
  • 打赏
  • 举报
回复
帮顶,思路没问题,感觉theforever的回答是正确的,你试试吧!
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 net205 的回复:]
问题时,在请求耗时长的web service同时,ajax也会获取当前进度并能返回,但就是不能改变进度条,直到最后一次才行。[/Quote]

大略看了一下,你最后一次才行,是因为在那个请求主体的AJAX的SUCCESS事件里写入100%.这是自然会成功的.
但为了获得中间的进度值,你还使用了另外一个$.getJSON.而这个的调用,intervalID = setInterval(RequestProcess, 500); 位置在$.ajax后面,这也没问题. 但问题是,你的$.ajax使用了"async: false,",这个是同步的方式.只有接收完毕,才能向下执行到intervalID = setInterval(RequestProcess, 500);这样的话,你取的进度还是已经完成的100%. 就是目前的现象了.

所以,这个只要把$.ajax的参数改成 async: true,就可以了.
wdzr_826 2010-09-13
  • 打赏
  • 举报
回复
这样是不行的,只有Response结束的时候才能触发Ajax的SuccessCallBack,你在Response.Write的时候并没有结束Response。建议你另做一个定时的Ajax(比方说20秒),这个Ajax用于检测当前的进度,然后返回进度的信息,并显示在processBar上。
plzzz 2010-09-13
  • 打赏
  • 举报
回复
有些不太明白... 你的 很多个Ajax 请求的是同一个后台线程?? 或者你有其它的方法
hoojo 2010-09-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 net205 的回复:]

to theforever:
帖子第一句我说明了思路,只是可能简单了一些,导致你没明白。下面我重新描述一下。
另外,我的代码是完整的实例代码。
to wdzr_826:
可能是我没讲清楚我的实现, 我的代码跟你说的是一样的。

情况是这样:
就是做一个网站备份恢复的功能,要恢复操作时需要耗时比较久(备份也一样),就像我上面的示例代码。
有一个web ser……
[/Quote]

一个ajax负责backup工作,可以在后台用一个线程模拟备份工作。将备份的进度保存在缓存中:session、application等
一个ajax用setTimeout、setInterval定时向服务器获取backup进度
net205 2010-09-13
  • 打赏
  • 举报
回复
to theforever:
帖子第一句我说明了思路,只是可能简单了一些,导致你没明白。下面我重新描述一下。
另外,我的代码是完整的实例代码。
to wdzr_826:
可能是我没讲清楚我的实现, 我的代码跟你说的是一样的。

情况是这样:
就是做一个网站备份恢复的功能,要恢复操作时需要耗时比较久(备份也一样),就像我上面的示例代码。
有一个web service,提供了2个操作,一个耗时很长的操作(包含把当前操作进度写入cache中),一个是获取当前进度的操作(从cache中获取当前进度)

然后客户端请求耗时长的web service时,会定时ajax请求获取当前进度并修改进度条( intervalID = setInterval(RequestProcess, 500); )

问题时,在请求耗时长的web service同时,ajax也会获取当前进度并能返回,但就是不能改变进度条,直到最后一次才行。

stackoverflow.com上有人的实例貌似,我试试再说。
  • 打赏
  • 举报
回复
需要的话,就通过站内短信和我联系.
  • 打赏
  • 举报
回复
说说你制作的思路,也许问题就有答案了.不要用代码来代替讲解,别人哪来工夫去看.真正需要看代码的,是实在没什么可讲的时候.

这种需求,我可以直接告诉你怎么做,按我说的重写就可以.或者等等看别人有耐心看过你的代码后是否能改动一小点就能解决问题的.
net205 2010-09-11
  • 打赏
  • 举报
回复

如图:前面的6,11,15,21...进度取到后不能即时显示出来,而到100时才显示100%和finished字符。

另外用蹩脚的英文发了一个蹩脚的帖子:
http://stackoverflow.com/questions/3690351/how-to-show-progress-immediately-using-ajax

87,907

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧