Evan You 10 лет назад
Родитель
Сommit
e71db5e86b
3 измененных файлов с 41 добавлено и 45 удалено
  1. 3 23
      src/server/create-renderer.js
  2. 6 22
      src/server/render-stream.js
  3. 32 0
      src/server/write.js

+ 3 - 23
src/server/create-renderer.js

@@ -3,8 +3,7 @@
 import RenderStream from './render-stream'
 import { createRenderFunction } from './render'
 import { warn } from 'core/util/debug'
-
-export const MAX_STACK_DEPTH = 1000
+import { createWriteFunction } from './write'
 
 export function createRenderer ({
   modules = [],
@@ -35,28 +34,9 @@ export function createRenderer ({
       done: (err: ?Error, res: ?string) => any
     ): void {
       let result = ''
-      let stackDepth = 0
-
-      const write = (text: string, next: Function) => {
-        if (write.caching && text) {
-          write.buffer += text
-        }
+      const write = createWriteFunction(text => {
         result += text
-        if (stackDepth >= MAX_STACK_DEPTH) {
-          process.nextTick(() => {
-            try { next() } catch (e) {
-              done(e)
-            }
-          })
-        } else {
-          stackDepth++
-          next()
-          stackDepth--
-        }
-      }
-      write.caching = false
-      write.buffer = ''
-
+      }, done)
       try {
         render(component, write, () => {
           done(null, result)

+ 6 - 22
src/server/render-stream.js

@@ -1,7 +1,7 @@
 /* @flow */
 
 import stream from 'stream'
-import { MAX_STACK_DEPTH } from './create-renderer'
+import { createWriteFunction } from './write'
 
 /**
  * Original RenderStream implmentation by Sasha Aickin (@aickin)
@@ -25,33 +25,17 @@ export default class RenderStream extends stream.Readable {
     this.expectedSize = 0
     this.stackDepth = 0
 
-    const write = this.write = (text: string, next: Function) => {
-      if (write.caching && text) {
-        write.buffer += text
-      }
+    this.write = createWriteFunction((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(() => {
-            try { next() } catch (e) {
-              this.emit('error', e)
-            }
-          })
-        } else {
-          this.stackDepth++
-          next()
-          this.stackDepth--
-        }
+        return true // we will decide when to call next
       }
-    }
-    write.caching = false
-    write.buffer = ''
+    }, err => {
+      this.emit('error', err)
+    })
 
     this.end = () => {
       // the rendering is finished; we should push out the last of the buffer.

+ 32 - 0
src/server/write.js

@@ -0,0 +1,32 @@
+/* @flow */
+
+const MAX_STACK_DEPTH = 1000
+
+export function createWriteFunction (
+  write: Function,
+  onError: Function
+): Function {
+  let stackDepth = 0
+  const cachedWrite = (text, next) => {
+    if (text && cachedWrite.caching) {
+      cachedWrite.buffer += text
+    }
+    const waitForNext = write(text, next)
+    if (!waitForNext) {
+      if (stackDepth >= MAX_STACK_DEPTH) {
+        process.nextTick(() => {
+          try { next() } catch (e) {
+            onError(e)
+          }
+        })
+      } else {
+        stackDepth++
+        next()
+        stackDepth--
+      }
+    }
+  }
+  cachedWrite.caching = false
+  cachedWrite.buffer = ''
+  return cachedWrite
+}