From a2d885c8baf8e023c9f8d9b9faac23d1f98bb334 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 25 Nov 2017 08:21:23 -0500 Subject: [PATCH] basic client-side await-then-catch working --- src/generators/dom/preprocess.ts | 11 +++++ src/generators/dom/visitors/AwaitBlock.ts | 44 ++++++++++++++----- .../samples/await-then-catch/_config.js | 9 ++-- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/generators/dom/preprocess.ts b/src/generators/dom/preprocess.ts index 7e0056b0ae..62768184a0 100644 --- a/src/generators/dom/preprocess.ts +++ b/src/generators/dom/preprocess.ts @@ -124,6 +124,8 @@ const preprocessors = { node.var = block.getUniqueName('await_block'); block.addDependencies(node.metadata.dependencies); + let dynamic = false; + [ ['pending', null], ['then', node.value], @@ -147,7 +149,16 @@ const preprocessors = { preprocessChildren(generator, child._block, child._state, child, inEachBlock, elementStack, componentStack, stripWhitespace, nextSibling); generator.blocks.push(child._block); + + if (child._block.dependencies.size > 0) { + dynamic = true; + block.addDependencies(child._block.dependencies); + } }); + + node.pending._block.hasUpdateMethod = dynamic; + node.then._block.hasUpdateMethod = dynamic; + node.catch._block.hasUpdateMethod = dynamic; }, IfBlock: ( diff --git a/src/generators/dom/visitors/AwaitBlock.ts b/src/generators/dom/visitors/AwaitBlock.ts index 2ebca07831..fc28091e84 100644 --- a/src/generators/dom/visitors/AwaitBlock.ts +++ b/src/generators/dom/visitors/AwaitBlock.ts @@ -51,15 +51,6 @@ export default function visitAwaitBlock( const create_then_block = node.then._block.name; const create_catch_block = node.catch._block.name; - const conditions = []; - if (node.metadata.dependencies) { - conditions.push( - `(${node.metadata.dependencies.map(dep => `'${dep}' in changed`).join(' || ')})` - ); - } - - conditions.push(`${promise} !== (${promise} = ${snippet})`); - block.addVariable(await_block); block.addVariable(await_block_type); block.addVariable(await_token); @@ -89,7 +80,10 @@ export default function visitAwaitBlock( // if we previously had a then/catch block, destroy it if (${await_block_type} !== ${create_pending_block}) { - if (${await_block}) ${await_block}.d(); + if (${await_block}) { + ${await_block}.u(); + ${await_block}.d(); + } ${await_block} = (${await_block_type} = ${create_pending_block})(${params}, ${resolved} = null, #component); return true; } @@ -120,6 +114,36 @@ export default function visitAwaitBlock( ${await_block}.m(${targetNode}, ${anchor}); `); + const conditions = []; + if (node.metadata.dependencies) { + conditions.push( + `(${node.metadata.dependencies.map(dep => `'${dep}' in changed`).join(' || ')})` + ); + } + + conditions.push( + `${promise} !== (${promise} = ${snippet})`, + `${handle_promise}(${promise}, ${params})` + ); + + if (node.pending._block.hasUpdateMethod) { + block.builders.update.addBlock(deindent` + if (${conditions.join(' && ')}) { + ${await_block}.c(); + ${await_block}.m(${anchor}.parentNode, ${anchor}); + } else { + ${await_block}.p(changed, ${params}, ${resolved}); + } + `); + } else { + block.builders.update.addBlock(deindent` + if (${conditions.join(' && ')}) { + ${await_block}.c(); + ${await_block}.m(${anchor}.parentNode, ${anchor}); + } + `); + } + block.builders.destroy.addBlock(deindent` ${await_token} = null; ${await_block}.d(); diff --git a/test/runtime/samples/await-then-catch/_config.js b/test/runtime/samples/await-then-catch/_config.js index 3c60bd64c9..9f03479d9c 100644 --- a/test/runtime/samples/await-then-catch/_config.js +++ b/test/runtime/samples/await-then-catch/_config.js @@ -5,8 +5,6 @@ let thePromise = new Promise(f => { }); export default { - solo: true, - data: { thePromise }, @@ -38,7 +36,12 @@ export default { `); reject(new Error('something broke')); - await thePromise; + + try { + await thePromise; + } catch (err) { + // do nothing + } assert.htmlEqual(target.innerHTML, `

oh no! something broke