我在通过 JavaScript 的新 Streams API 使用来 self 的 WebFlux 服务器的响应时遇到问题。
我可以通过 Curl(在 --limit-rate
的帮助下)看到服务器正在按预期速度减慢,但是当我尝试在 Google Chrome (64.0.3282.140) 中使用 body 时),它并没有像它应该的那样减速。事实上,Chrome 从服务器下载并缓冲了大约 32 兆字节,尽管只有大约 187 kB 被传递给 write()
。
我的 JavaScript 有问题吗?
async function fetchStream(url, consumer) {
const response = await fetch(url, {
headers: {
"Accept": "application/stream+json"
}
});
const decoder = new TextDecoder("utf-8");
let buffer = "";
await response.body.pipeTo(new WritableStream({
async write(chunk) {
buffer += decoder.decode(chunk);
const blocks = buffer.split("\n");
if (blocks.length === 1) {
return;
}
const indexOfLastBlock = blocks.length - 1;
for (let index = 0; index < indexOfLastBlock; index ++) {
const block = blocks[index];
const item = JSON.parse(block);
await consumer(item);
}
buffer = blocks[indexOfLastBlock];
}
}));
}
根据the specification for Streams ,
If no strategy is supplied, the default behavior will be the same as a CountQueuingStrategy with a high water mark of 1.
所以它应该减慢 consumer(item)
返回的 promise 解析速度非常慢,对吧?
最佳答案
查看 Backpressure support in the Streams API ,似乎背压信息是在 Streams 链内而不是通过网络进行通信的。在这种情况下,我们可以假设某处有一个无界队列,这可以解释您所看到的行为。
这other github issue表明背压信息确实停止在 TCP 级别 - 它们只是停止从 TCP 套接字读取,这取决于当前的 TCP 窗口大小/TCP 配置,这意味着缓冲区将被填充,然后 TCP 流量控制开始。作为这个问题状态,他们不能手动设置窗口大小,他们必须让 TCP 堆栈从那里处理事情。
HTTP/2 支持协议(protocol)级别的流量控制,但我不知道浏览器实现是否通过 Streams API 来利用它。
我无法解释您所看到的行为差异,但我认为您可能在此处阅读了太多关于背压支持的内容,并且这根据规范按预期工作。
关于javascript - fetch() 的背压在 Google Chrome 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48794351/