Skip to content

Commit

Permalink
Simplify handling synchronously resolved promises [refactor]
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Feb 20, 2019
1 parent a9e19e8 commit 051ef50
Showing 1 changed file with 44 additions and 33 deletions.
77 changes: 44 additions & 33 deletions lib/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,64 +323,62 @@ class PartialRenderer extends ReactDOMServerRenderer {
const {stack} = this;
const frame = this.stackPopOriginal.call(stack);

// Add node to tree
const node = this.createChildWithStackState(TYPE_PROMISE, frame);
node.element = element;
node.promise = promise;
node.resolved = false;

// Follow promise
this.numAwaiting++;

let sync = true, resolvedSync = false;
let node;
promise.then(
() => {
// If node is no longer going to be rendered because boundary
// fallback above has already triggered, ignore result.
// Also ignore if callback called more than once.
if (node.resolved) return;
node.resolved = true;

// Handle synchronous callback
if (sync) {
resolvedSync = true;
if (!node) {
node = {resolved: true};
return;
}

this.resolved(node);
},
err => {
// Swallow errors where node is not going to be rendered
if (node.resolved) return;
node.resolved = true;

// Promise is no longer awaited
this.numAwaiting--;
// Handle synchronous callback - throw error
if (!node) {
node = {resolved: true};
throw err;
}

// Abort all rendering
this.halt(err);
this.rejected(node, err);
}
);
sync = false;

// If Promise resolved synchronously, push element back onto stack so it renders again
if (resolvedSync) {
// Push element onto stack
frame.children = toArray(element);
stack.push(frame);
if (node) {
// Create tree node and step into it
node = this.createChild(TYPE_PROMISE);
node.resolved = true;

// Step into this node
node.frame = frame;
this.node = node;
this.nonDomFrames++;

// Promise is no longer awaited
this.numAwaiting--;
// Push element onto stack
frame.children = toArray(element);
stack.push(frame);

return;
}

// Awaiting promise - create tree node
node = this.createChildWithStackState(TYPE_PROMISE, frame);
node.element = element;
node.promise = promise;
node.resolved = false;

this.numAwaiting++;
}

resolved(node) {
// If node is no longer going to be rendered because boundary
// fallback above has already triggered, ignore result.
if (node.resolved) return;

// Promise is no longer awaited
node.resolved = true;
this.numAwaiting--;

// Step into node and reinstate stack state with element on stack ready to render
Expand All @@ -395,6 +393,19 @@ class PartialRenderer extends ReactDOMServerRenderer {
this.resetProviders();
}

rejected(node, err) {
// If node is no longer going to be rendered because boundary
// fallback above has already triggered, swallow error.
if (node.resolved) return;

// Promise is no longer awaited
node.resolved = true;
this.numAwaiting--;

// Abort all rendering
this.halt(err);
}

restoreStack(stackState, element) {
// Reinstate stack state with element on stack ready to render
const frame = {
Expand Down

0 comments on commit 051ef50

Please sign in to comment.