4

这是我所拥有的:

  1. 一个执行长时间(2-10 秒)计算(db + 外部 API 调用)的 Node.js 函数。我async.auto()用来组织调用的依赖项
  2. HTML 视图页面上一个漂亮的视觉进度条
  3. 调用查询的 getJSON 函数(参见下面的代码)

现在,我只是在更新计时器上的进度条。但我希望它更准确。我已经将服务器端功能分解为 5 个里程碑(即在每个外部调用成功完成之后),我想将该进度信息发送给客户端。但是,一旦您res.send(progress)完成了回复,就无法再发送任何内容了。

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

  1. 2个ajax调用,一个轮询进度,第二个得到结果
  2. 一个调用被调用 5 次,直到服务器端函数消失
  3. 完全不同的东西(可能是长轮询,websockets,?)

问题:

我想知道推荐的模式是什么,以及如何在服务器端和客户端实现它。非常感谢示例代码或示例链接!

而且,一如既往,感谢您的宝贵时间!

这里包括的是我到目前为止的代码(有明显的功能遗漏)。回答这个问题并不是绝对必要的,但我在这里提供它是为了提供一些背景信息。

客户

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

2 回答 2

2

我的第一个想法是使用 socket.io 或类似的东西,服务器在每个里程碑发出一个事件。searchFunction() 的客户端版本将简单地进行 AJAX 调用然后返回,而套接字处理程序负责更新进度条。

于 2012-10-06T03:13:57.420 回答
2

您可以使用事件流将完成百分比值推送回客户端。但它只适用于现代浏览器。IE9+ 我相信。这是一个示例事件流: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; }

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

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/基于百分比的宽度的孩子。那得到更新。

于 2012-10-06T05:36:54.843 回答