拿那篇文章中的php显示页做示例:
先输出页面的主体结构:
然后按顺序更新页面的内容:
2s后输出header
4s后输出content
6s后输出footer
从加载到显示共消耗约13s (2 + 4 + 6 + 1 ~= 13s),符合预期结果
这个示例的源码(可复制至本地直接运行):
/** * Created with JetBrains WebStorm. * User: Meteoric_cry * Date: 13-4-13 * Time: 上午11:10 * To change this template use File | Settings | File Templates. */ var http = require('http'); var server = http.createServer(function(req, res) { res.writeHead(200, { 'Content-Type' : 'text/html', 'Transfer-Encoding' : 'chunked' }); res.write([ '<!DOCTYPE html>', '<html>', '<head>', '<meta charset="utf-8">', '<title>Node.js Bigpipe Demo</title>', '<style type="text/css">', ' * {margin: 0; padding:0;}', ' body {background-color:#fff;}', ' div{border:2px solid #4F81BD; margin:30px; padding: 10px;}', ' p {word-wrap:break-wrod; word-break:break-all; color: #666;}', ' .red {color: #f00;}', ' .blue {color:blue;}', ' .green {color:green;}', '</style>', '<script>', 'var g_startTime = new Date();', 'var g_renderArr = []', 'function render(nodeID,html){', ' g_renderArr.push(new Date())', ' document.getElementById(nodeID).innerHTML=html;', '}', '</script>', '</head>', '<body>', '<div id="header"><p>Loading...</p></div>', '<div id="content"><p>Loading...</p></div>', '<div id="footer"><p>Loading...</p></div>' ].join('\r\n')); function out_header() { res.write("<script type='text/javascript'>render('header', '<p><span class=\"blue\">111111</span></p>');</script>\r\n"); setTimeout(out_content, 4 * 1000); } function out_content() { res.write("<script type='text/javascript'>render('content', '<p><span class=\"red\">222222</span></p>');</script>\r\n"); setTimeout(out_footer, 6 * 1000); } function out_footer() { res.write("<script type='text/javascript'>render('footer', '<p><span class=\"green\">333333</span></p>');</script>\r\n"); setTimeout(out_end, 1 * 1000); } function out_end() { res.write([ '<script>', 'var str = [', ' "start:" + g_startTime.toGMTString(),', ' "header:" + g_renderArr[0].toGMTString() + "-" + (g_renderArr[0] - g_startTime) / 1000,', ' "content:" + g_renderArr[1].toGMTString() + "-" + (g_renderArr[1] - g_renderArr[0]) / 1000,', ' "footer:" + g_renderArr[2].toGMTString() + "-" + (g_renderArr[2] - g_renderArr[1]) / 1000,', ' "end:" + new Date().toGMTString() + "-" + (new Date() - g_renderArr[2]) / 1000 + "-" + (new Date() - g_startTime) / 1000', '].join("\\n");', 'alert(str);', '</script>' ].join('')); res.end("\r\n</body></html>"); } setTimeout(out_header, 2 * 1000); }).listen(3002);
上面是将界面的显示顺序固定写死了,下面将展示一个灵活的动态界面:
先输出6个内容容器,然后构建6个客户端请求,当收到请求数据时直接返回给客户端。如果你需要让界面的内容按顺序显示,只需要修改,返回的delay值,比如按索引值的大小进行修改
1: var params = url.parse(request.url, true);
2: var delay = params.query.id * 3000; console.log(delay);
这个示例的完整源码:
/** * Created with JetBrains WebStorm. * User: zhangyi * Date: 13-4-23 * Time: 上午10:57 * To change this template use File | Settings | File Templates. */ var http = require('http'); var sys = require('sys'); var url = require("url"); http.createServer(function(request, response) { response.writeHead(200, {"Content-Type" : "text/html"}); response.write("<!Doctype html><html><head>"); response.write("<style type='text/css'>div{border:2px solid #4F81BD; margin:30px; padding: 10px;}</style>"); response.write("<script type=\"text/javascript\">function arrived(id,text) { var b=document.getElementById(id); b.innerHTML = text; }</script>"); response.write("</head><body><div>Progressive Loading"); for(var i = 0; i < 6; i++) { response.write("<div id='" + i + "'>Loading...</div>"); } response.write("</div>"); var down = 6; for (i = 0; i < 6; i++) { var proxy = http.createClient(2000, "localhost"); var proxyRequest = proxy.request("GET", "/?id=" + i, {"host" : "localhost"}); proxyRequest.addListener('response', function (proxyResponse) { --down; proxyResponse.addListener('data', function(chunk) { response.write(chunk, 'binary'); }); proxyResponse.addListener('end', function() { if(down == 0) { response.end(); } }); }); proxyRequest.end(); } response.write("</body></html>"); }).listen(8080); http.createServer(function(request, response) { var delay = Math.round(Math.random() * 8000); /* var params = url.parse(request.url, true); var delay = params.query.id * 3000; console.log(delay); */ setTimeout(function() { var params = url.parse(request.url, true); var id = params.query.id; response.writeHead(200, {"Content-Type" : "text/html"}); var content = "<span>Content of Module " + id + "</span>"; response.write("<script>" + "arrived('" + id + "', '" + content + "');" + "</script>"); response.end(); }, delay); }).listen(2000);
上面的示例中并没有像第一个例子一样,显示输出header信息('Transfer-Encoding' : 'chunked'),而浏览器,在response里却看到了,猜测是node.js在输出的时候内部加上去的。
相比php,node.js内部实现并没有“缓冲池”的功能,都是直接输出,很简单吧…