如何实现实时的进度条?

2016-10-28 19:26:34 +08:00
 pppy
提交数据后,可能需要时间执行,后端如何与前端保持一个同步的进度显示?
比如后台执行到 20% 前端就显示 20%
7598 次点击
所在节点    Python
21 条回复
lcorange
2016-10-28 19:36:40 +08:00
1. 前台 js 定时访问拿数据
2. websocket
alqaz
2016-10-28 20:07:44 +08:00
难点估计不在交互,在于怎么判断任务执行百分比
mayne95
2016-10-28 20:55:05 +08:00
后端执行一点功能就往前面返回一个状态。感觉这么搞负担好大。而且我看网站都是一点就过去了,速度都很快,单纯的为了视觉效果弄个假的糊弄算了。 gmail 加载好像跟你这个需求差不多。
ihuotui
2016-10-28 20:59:13 +08:00
大概就行了,根据数据量预估一个时间,然后剩下一点等待服务器返回成功
Powered
2016-10-28 21:08:48 +08:00
三种思路:

1. WebSocket
2. 内嵌一个 iframe,写一个 timer 不停去刷新 iframe 中的内容(iframe 的 src 属性指向你的长耗时任务的 URL),根据内容字符串的最后一个百分号的值,获得进度。
3. 使用 ajax XMLHttpRequest level 2 API

给出一个例子:

后端:

```javascript
'use strict';

const http = require('http');

const server = http.createServer();
server.on('request', function(req, res) {
console.log('HTTP', req.method, req.url);
let n = 0;
res.writeHead(200, {
'Content-Type': 'text/plain',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*',
'Content-Length': 100
});

const inter = setInterval(function() {
res.write('.');
n++;
if (n >= 100) {
clearInterval(inter);
res.end();
}
}, 50);

res.on('error', function(err) {
console.log(err);
});

res.on('close', function() {
console.log('Connection close');
})
});

server.listen(8000);

```


前端:

```html
<!DOCTYPE html>
<HTML>
<head>
<meta charset="utf-8"/>
<style>
.progress-bar {
border: 1px solid rgb(230, 230, 230);
padding: 0px;
position: relative;
height: 4px;
border-radius: 2px;
}

.progress-bar > .progress-bar-inner {
margin: 0px;
width: 30%;
background-color: rgb(0, 180, 20);
height: 4px;
border-radius: 2px;
}
</style>
</head>
<body>
<div class="progress-bar">
<div id="pro" class="progress-bar-inner"></div>
</div>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
var progress = $('#pro');
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8000/', true);
xhr.onprogress = function(event) {
if (event.lengthComputable) {
var pro = event.loaded/event.total;
console.log(pro);
progress.css('width', pro*100 + '%');
}
};
xhr.send();
</script>
</body>
</HTML>
```
Powered
2016-10-28 21:09:13 +08:00
上面的例子使用使用 ajax XMLHttpRequest level 2 API 做的
eyp82
2016-10-28 21:10:34 +08:00
没有必要, 你观察一下就会发现大多数的进度条都是假的, 只是视觉安慰而已.
除非你真的需要根据这个进度条精确定位(但其实这个很难, 比如很难估计一项任务到底要花多少时间)
shlabc
2016-10-28 21:20:59 +08:00
前端用 Flash 编程,可以做到实时
adv007
2016-10-28 22:10:59 +08:00
@shlabc 啥年代了,还 fla
adv007
2016-10-28 22:11:34 +08:00
websocket http-chunk
shlabc
2016-10-28 22:17:41 +08:00
@adv007 呵呵,我只是说这个技术绝对能做到啊
silencefent
2016-10-28 23:08:25 +08:00
卡 99%好吧,解决了就 100%
SourceMan
2016-10-28 23:10:24 +08:00
你看看苹果的"少于一分钟",你就知道你现在这个需求有没有意义了
guyskk
2016-10-29 00:58:54 +08:00
我记得有个讨论是说: 数据是从客户端发送出去的,客户端本身就应该知道已经发送了多少数据,也就能知道百分比,为何要询问服务端自己已经知道的事情?

现在 XMLHttpRequest 有上传进度的接口,具体可以在 MDN 找到。 5 楼的实现是正确的,也可以去翻 jQuery 等涉及 AJAX 的库源码,应该能找到上传进度的实现,我之前也是在一个库里看到的,不过一时找不到在哪了。
akmonde
2016-10-29 09:36:29 +08:00
很多进度条都是假的,一般按大段的工作进度来分。
qwer1234asdf
2016-10-29 14:38:46 +08:00
ajaxForm
qwer1234asdf
2016-10-29 14:57:28 +08:00
coolloves
2016-10-29 17:22:48 +08:00
马克,关注下
Mark24
2016-10-29 18:23:20 +08:00
前天洗澡的时候也想过这个问题。
可以建立一个 cache=[ ], 在里面塞任务队列,然后计算长度,完成一个往前推进一步。恩,至少这个是可行的。
Tyanboot
2016-10-29 19:53:22 +08:00
@guyskk 他说的应该是那种,前端发送数据之后,后端需要长时间执行然后返回结果的那种吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/316281

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX