在漫长的ajax查询进度条更新模式 [英] Update pattern for progress bar on a long ajax query

查看:149
本文介绍了在漫长的ajax查询进度条更新模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我有:

  1. 在一个Node.js的函数来执行长(2-10秒)计算(DB +外部API调用)。我用 async.auto()来组织我的电话的依赖
  2. HTML视图页面上一个漂亮的可见的进度条
  3. 一个的getJSON函数调用查询(见下文code)

现在,我只是更新一个计时器进度条。但我想它会更准确。我已经打破了服务器端功能5里程碑(即后每隔外部调用成功完成),我想发送进度信息给客户端。然而,一旦你 res.send(进度)您完成响应,仅此而已,可以在其上发送。

我显然需要一个不同的模式在这里,我有一些想法:

  1. 2 Ajax调用,一是调查的进展情况,第二得到的结果
  2. 在一个电话被调用5次,直到服务器端功能不见了
  3. 完全不同的东西(也许长轮询,WebSockets的,?)

的问题:

我想知道什么是推荐的方式,以及如何实现它在服务器和客户端上。样品code或链接样品,具有很强的AP preciated!

和,一如既往,感谢您的时间!

这里包括为code我至今(有明显的功能遗漏)。这不是绝对必要回答这个问题,但我仍在这里提供它给一些背景。

客户端

  VAR searchFunction =功能(){
        。VAR用户= $(#搜索关键词)VAL();
        $ .getJSON(/搜索/+的用户,功能(数据){
            的console.log(数据);
            ko.applyBindings(新MyViewModel(数据));
        });
        $(#内容)隐藏()。
        进度条(5);
        $(#progress_bar)显示()。
        的setTimeout(函数(){
            进度条(25);
        },1000);
        的setTimeout(函数(){
            进度条(50);
        },2000);
        的setTimeout(函数(){
            进度条(75);
        },3000);
        的setTimeout(函数(){
            $(#progress_bar)隐藏()。
            $(#内容)显示()。
        },4000);
    };
 

服务器

  VAR searchFunction =功能(REQ,RES){
    async.auto({
        F1:函数(回调){
            //事情发生
            回调(ERR,RES);
        },
        F2:函数(回调){
            //事情发生
            回调(ERR,RES);
        },
        F3:['F2',函数(回调,结果){
            //很多事情发生
            回调(ERR,RES);
        },
        功能(错误){
            //做出决定
            回调(NULL,观察家);
        }]
    },功能(错了,结果){
            //更令人兴奋的事情发生
            res.send(finalResults);
        }
    );
};
 

解决方案

您可以使用一个事件流,以百分比完成值推送至客户端。但它只能在现代浏览器。 IE9 +我相信。下面是一个例子事件流: https://github.com/chovy/nodejs-stream

HTML

 < D​​IV ID =进步><跨度类=酒吧>< / SPAN>< / DIV>
 

CSS

  #progress {宽度:200像素;背景:#eee;边界:1px的固体#ccc;高度:20像素; }
#progress的.bar {显示:inline-block的;背景:#ddd;宽度:0; }
 

客户端(jQuery的) - 听/ progress事件流

 无功源=新的EventSource(进步);
source.addEventListener('进步',功能(五){
  VAR百分比= JSON.parse(e.data)
  //在客户端的更新进度条
  $(#进步的.bar​​)的CSS({宽度:百分比});
}, 假);
 

服务器端 - 推送事件新的进展%的

  res.writeHead(200,{内容类型:文/事件流'});
res.write(事件:进步的\ n);
//推百分比到客户机(即:10%)
res.write(数据:+10%的toString()+\ñ\ N);
 

这将是由你来定义用户界面的进度条---我会用一个固定宽度的div有孩子,有CSS规则瓦特/基于百分比的宽度。这得到更新。

Here's what I have:

  1. a Node.js function that performs a long (2-10 seconds) calculation (db + external API calls). I use async.auto() to organize my calls' dependencies
  2. a nice visual progress bar on the HTML view page
  3. a getJSON function calling the query (see code below)

Right now, I'm just updating the progress bar on a timer. But I'd like it to be more accurate. I already broke the server side function to 5 milestones (i.e. after every external call finishes successfully), and I'd like to send that progress info to the client. However, once you res.send(progress) you complete the response and nothing more could be sent on it.

I obviously need a different pattern here, and I had some ideas:

  1. 2 ajax calls, one polls for progress and the second gets the results
  2. one call that gets called 5 times, until the server side function is gone
  3. Something completely different (maybe long polling, websockets, ?)

The question:

I'd like to know what's the recommended pattern, and how to implement it on both the server and client side. Sample code, or links to samples, are highly appreciated!

And, as always, thanks for your time!

Included here is the code I have so far (with obvious functionality omissions). It's not strictly necessary to answer this question, but I provide it here to give some context.

Client

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);
    };

Server

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);
        }
    );
};

解决方案

You could use an event stream to push a percent-complete value back up to the client. But it only works in modern browsers. IE9+ I believe. Here's an example event stream: https://github.com/chovy/nodejs-stream

html

<div id="progress"><span class="bar"></span></div>

css

#progress { width: 200px; background: #eee; border: 1px solid #ccc; height: 20px; }
#progress .bar { display: inline-block; background: #ddd; width: 0; }

client side (jQuery) - listen to /progress event stream

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);

server side - push an event with new progress percent

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");

It would be up to you to define your progress bar in the UI --- I would use a fixed width div with a child that has css rule w/ percentage-based width. That gets updated.

这篇关于在漫长的ajax查询进度条更新模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆