diff --git a/src/html.js b/src/html.js index bd90b2b..8982ec7 100644 --- a/src/html.js +++ b/src/html.js @@ -93,22 +93,35 @@ function processChildren(stream, children, options, callback) { continue; } + let _callback = function() { + let res = callback.apply(null, arguments); + let next = i + 1; + if(next < children.length) { + let remainder = children.slice(next); + if(nonBlocking) { + process.nextTick(_ => + processChildren(stream, remainder, options, callback)); + } else { + processChildren(stream, remainder, options, callback); + } + } + return res; + }; + let { nonBlocking, log, _idRegistry } = options; let generatorOptions = { nonBlocking, log, _idRegistry }; if(child.length !== 1) { // element generator -- XXX: brittle heuristic (arity) - child(stream, generatorOptions, callback); - continue; + if(nonBlocking) { + child(stream, generatorOptions, _callback); + break; + } else { + child(stream, generatorOptions, callback); + continue; + } } // deferred child element - let fn = element => { - element(stream, generatorOptions, callback); - let next = i + 1; - if(next < children.length) { - let remainder = children.slice(next); - processChildren(stream, remainder, options, callback); - } - }; + let fn = element => element(stream, generatorOptions, _callback); if(!nonBlocking) { // ensure deferred child element is synchronous let invoked = false; diff --git a/test/test_renderer.js b/test/test_renderer.js index 05943ee..ed09325 100644 --- a/test/test_renderer.js +++ b/test/test_renderer.js @@ -42,6 +42,18 @@ describe("renderer", _ => { done(); }); + it("should support non-blocking mode", done => { + let { renderer, stream } = setup(); + + /* eslint-disable indent */ + renderer.renderView(NonBlockingContainer, null, stream, { fragment: true }, _ => { + assert.equal(stream.read(), + "

lorem ipsum

"); + done(); + }); + /* eslint-enable indent */ + }); + it("should detect non-blocking child elements in blocking mode", done => { let { renderer, stream } = setup();