ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] ***** ## 1 render-stream.js 流式渲染 >[info] import ~~~ import stream from 'stream' ~~~ >[info] module ~~~ const MAX_STACK_DEPTH = 1000 ;渲染流 export default class RenderStream extends stream.Readable { constructor (render) { super() this.buffer = '' this.render = render this.expectedSize = 0 this.write = (text, next) => { const n = this.expectedSize this.buffer += text if (this.buffer.length >= n) { this.next = next this.pushBySize(n) } else { // continue rendering until we have enough text to call this.push(). // sometimes do this as process.nextTick to get out of stack overflows. if (this.stackDepth >= MAX_STACK_DEPTH) { process.nextTick(next) } else { this.stackDepth++ next() this.stackDepth-- } } } this.end = () => { // the rendering is finished; we should push out the last of the buffer. this.done = true this.push(this.buffer) } } pushBySize (n) { const bufferToPush = this.buffer.substring(0, n) this.buffer = this.buffer.substring(n) this.push(bufferToPush) } _read (n) { this.expectedSize = n // it's possible that the last chunk added bumped the buffer up to > 2 * n, // which means we will need to go through multiple read calls to drain it // down to < n. if (this.done) { this.push(null) return } if (this.buffer.length >= n) { this.pushBySize(n) return } if (!this.next) { this.stackDepth = 0 // start the rendering chain. this.render(this.write, this.end) } else { // continue with the rendering. this.next() } } } ~~~ >[info] export ~~~ ~~~