javascript - fetch() 的背压在 Google Chrome 中不起作用

标签 javascript google-chrome reactive-programming spring-webflux reactive-streams

我在通过 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/

相关文章:

javascript - 如何让 "display: none"元素出现

javascript - 使用 javascript 定位元素内的特定元素

php - 将文件夹内容中的单个 img src 读取为 HTML

javascript - 如何捕获或收听浏览器通知?

css - Chrome 和 Mozilla 计算 margin 的方式不同

c# - C# 中的计算数组值 - 响应式(Reactive)编程

javascript - 为什么并行运行 AJAX 查询比串行运行慢得多?

javascript - localStorage 在 chrome mobile android 中为 null

javascript - 使用 RxJS 重置事件超时

c# - ReactiveUI WPF - 调用线程无法访问此对象,因为另一个线程拥有它