在长ajax查询上更新进度条的模式
这就是我所拥有的:
- 一个Node.js函数,执行长(2-10秒)计算(db +外部API调用)。 我使用
async.auto()
来组织我的调用的依赖项 - HTML视图页面上的一个很好的可视化进度条
- 调用查询的getJSON函数(参见下面的代码)
现在,我只是更新计时器上的进度条。 但我希望它更准确。 我已经将服务器端function打破了5个里程碑(即每次外部呼叫成功完成后),我想将该进度信息发送给客户端。 但是,一旦你res.send(progress)
你完成了响应,就不能再发送它了。
我显然需要一个不同的模式,我有一些想法:
- 2 ajax调用,一个轮询进度,第二个得到结果
- 一次调用被调用5次,直到服务器端function消失
- 完全不同的东西(也许长轮询,websockets,?)
问题是:
我想知道推荐的模式是什么,以及如何在服务器端和客户端实现它。 示例代码或样本链接非常感谢!
而且,一如既往,谢谢你的时间!
这里包含我到目前为止的代码(具有明显的function遗漏)。 回答这个问题并不是绝对必要的,但我在这里提供一些背景。
客户
var searchFunction = function() { var user = $("#searchTerm").val(); $.getJSON("/search/" + user, function(data) { console.log(data); ko.applyBindings(new MyViewModel(data)); }); $("#content").hide(); progressBar(5); $("#progress_bar").show(); setTimeout(function() { progressBar(25); }, 1000); setTimeout(function() { progressBar(50); }, 2000); setTimeout(function() { progressBar(75); }, 3000); setTimeout(function() { $("#progress_bar").hide(); $("#content").show(); }, 4000); };
服务器
var searchFunction = function(req, res) { async.auto({ f1: function(callback) { //things happen callback(err, res); }, f2: function(callback) { //things happen callback(err, res); }, f3: ['f2', function(callback, result) { //many things happen callback(err, res); }, function(err) { //decisions are made callback(null, watchers); }] }, function(err, result) { //more exciting stuff happens res.send(finalResults); } ); };
您可以使用事件流将百分比完成值反馈回客户端。 但它只适用于现代浏览器。 IE9 +我相信。 这是一个示例事件流: https : //github.com/chovy/nodejs-stream
HTML
CSS
#progress { width: 200px; background: #eee; border: 1px solid #ccc; height: 20px; } #progress .bar { display: inline-block; background: #ddd; width: 0; }
客户端(jQuery) – 监听/进度事件流
var source = new EventSource('progress'); source.addEventListener('progress', function(e) { var percentage = JSON.parse(e.data), //update progress bar in client $("#progress .bar").css({ width: percentage }); }, false);
服务器端 – 使用新进度百分比推送事件
res.writeHead(200, {'Content-Type': 'text/event-stream'}); res.write("event: progress\n"); //push the percentage to the client (ie: "10%") res.write("data: "+"10%".toString()+"\n\n");
你可以在UI中定义你的进度条 – 我会使用一个固定宽度的div与一个有css规则w /百分比宽度的孩子。 这会得到更新。
我的第一个想法是使用socket.io或类似的东西,服务器在每个里程碑发出一个事件。 searchFunction()的客户端版本将简单地进行AJAX调用然后返回,套接字处理程序负责更新进度条。