给定以下javascript伪代码(示例1(,
如您所见,有3 async streams
反过来写入响应。它们当然会以异步方式写入响应,因此不会保留块的顺序(实际上是不可预测的(。
import pre from './pre';
import content from './content';
import post from './post';
export function renderIndex(req, res) {
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8',
'Transfer-Encoding': 'chunked',
});
const onEnd = () => {
if(!pre._readableState.ended) return;
if(!body._readableState.ended) return;
if(!post._readableState.ended) return;
res.end();
};
pre.on('data', (chunk) => { res.write(chunk); }).on('end', onEnd);
body.on('data', (chunk) => { res.write(chunk); }).on('end', onEnd);
post.on('data', (chunk) => { res.write(chunk); }).on('end', onEnd);
}
是否可以告诉客户端每个数据块的位置?
我想实现这样的事情:
// ---- Stream 1 keep open
<html>
<head>
...
...
...
...
// --- Stream 2 keep open
<body>
...
...
...
// --- Stream 3 keep open
<script src="..."></script>
<script src="..."></script>
<script src="..."></script>
// --- Stream 1 CLOSE
</head>
// --- Stream 2 CLOSE
</body>
// --- Stream 3 CLOSE
</html>
// res.end()
- 范围请求
- 多部分范围
大理石般的解释:
- 实际:
[pre] [post] [body] [pre] [body] [/pre] [/post] [/body]
- 期望
[pre] [/pre] [body] [/body] [post] [/post]
我相信你可以通过一个名为highland.js的库来实现预期的行为。它为您提供了一种在流之上执行某些操作的方法
/*
the sample to show how it works
H([
H([1, 2, 3]),
H([4, 5, 6])
]).sequence().pipe(process.stdout);
*/
import pre from './pre';
import content from './content';
import post from './post';
const H = require('highland')
export function renderIndex(req, res) {
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8',
'Transfer-Encoding': 'chunked',
});
H([
pre,
content,
post
]).sequence().pipe(res);
}
解决该问题的最简单方法是将块写入专用变量,并在end
事件上,将整个前/正文/后响应写入res
。