desiredSize是可写流实时反映缓冲区剩余空间的动态差值指标,等于highWaterMark减当前队列字节数(或对象数),用于主动流控而非被动响应压力。

可写流的 desiredSize 是一个实时、轻量、无需轮询的反馈指标,它直接反映当前可写流内部缓冲区的“剩余空间”,本质是下游消费能力的镜像——值越大,说明积压越少、压力越低;值越小(甚至为负),说明缓冲区趋近饱和、下游已滞后。
desiredSize 的真实含义与计算逻辑
desiredSize 不是固定阈值,而是动态差值:
desiredSize = highWaterMark − 当前内部队列字节数(或对象数)
当流处于 objectMode 时,它表示还可写入多少个 JS 对象;默认二进制模式下,则表示还可写入多少字节。一旦该值 ≤ 0,writableStream.writable 仍为 true,但 writableStream.writableStrategy.size() 已判定不可写,此时调用 writer.write() 将返回 pending Promise,且不会立即入队。
在写入前主动检查水位,避免盲目推送
不要依赖 write() 的返回值做流控判断(它只反映是否入队成功,不体现压力趋势)。应每次写入前读取 desiredSize 做决策:
- 若
desiredSize > highWaterMark * 0.7:下游宽松,可批量写入(如一次 push 3–5 个 chunk) - 若
0 :缓冲区已满 80%,应降速,改用单次 write + await,等待自然释放 - 若
desiredSize ≤ 0:必须暂停写入,监听writableStream.on('drain')或 awaitwriter.ready恢复
结合 controller.signal 实现响应式暂停/恢复
在自定义 underlyingSink.write() 中,可通过 controller.signal 监听流状态变化,但更实用的是利用 desiredSize 主动调节生产节奏。例如在生成模拟数据的循环中:
- 不使用
while(true)疯狂 write - 改为:每次写入后
await writer.ready,并在下一次写入前检查writable.desiredSize - 当
desiredSize持续低于阈值(如连续 3 次 await new Promise(r => setTimeout(r, 10)) 微休眠
注意与 Netty 水位线的对应关系
Web Streams 的 desiredSize 和 Netty 的 WriteBufferWaterMark 逻辑一致:都是基于缓冲区容量与当前占用的差值反馈压力。Netty 中 channel.isWritable() 对应的是 desiredSize > 0;而 channel.bytesBeforeUnwritable 则近似于 desiredSize 的原始数值。二者都要求上游**主动查询、自主节制**,而非等待 onError 或 OOM 后被动处理。

















