preserve outer context for await blocks - fixes #1251

pull/1379/head
Rich Harris 7 years ago
parent ed605bfa79
commit 5fd4965b64

@ -98,6 +98,8 @@ export default class AwaitBlock extends Node {
block.addVariable(promise); block.addVariable(promise);
block.addVariable(resolved); block.addVariable(resolved);
block.maintainContext = true;
// the `#component.root.set({})` below is just a cheap way to flush // the `#component.root.set({})` below is just a cheap way to flush
// any oncreate handlers. We could have a dedicated `flush()` method // any oncreate handlers. We could have a dedicated `flush()` method
// but it's probably not worth it // but it's probably not worth it
@ -119,13 +121,12 @@ export default class AwaitBlock extends Node {
} }
} }
function ${handle_promise}(${promise}, ctx) { function ${handle_promise}(${promise}) {
var ${token} = ${await_token} = {}; var ${token} = ${await_token} = {};
if (@isPromise(${promise})) { if (@isPromise(${promise})) {
${promise}.then(function(${value}) { ${promise}.then(function(${value}) {
${this.value ? deindent` ${this.value ? deindent`
var ctx = #component.get();
${resolved} = { ${this.value}: ${value} }; ${resolved} = { ${this.value}: ${value} };
${replace_await_block}(${token}, ${create_then_block}, @assign(@assign({}, ctx), ${resolved})); ${replace_await_block}(${token}, ${create_then_block}, @assign(@assign({}, ctx), ${resolved}));
` : deindent` ` : deindent`
@ -133,7 +134,6 @@ export default class AwaitBlock extends Node {
`} `}
}, function (${error}) { }, function (${error}) {
${this.error ? deindent` ${this.error ? deindent`
var ctx = #component.get();
${resolved} = { ${this.error}: ${error} }; ${resolved} = { ${this.error}: ${error} };
${replace_await_block}(${token}, ${create_catch_block}, @assign(@assign({}, ctx), ${resolved})); ${replace_await_block}(${token}, ${create_catch_block}, @assign(@assign({}, ctx), ${resolved}));
` : deindent` ` : deindent`
@ -155,7 +155,7 @@ export default class AwaitBlock extends Node {
} }
} }
${handle_promise}(${promise} = ${snippet}, ctx); ${handle_promise}(${promise} = ${snippet});
`); `);
block.builders.create.addBlock(deindent` block.builders.create.addBlock(deindent`

@ -0,0 +1,31 @@
let fulfil;
let thePromise = new Promise(f => {
fulfil = f;
});
const items = [{
title: 'a title',
data: thePromise
}];
export default {
data: {
items
},
html: `
<p>a title: loading...</p>
`,
test(assert, component, target) {
fulfil(42);
return thePromise
.then(() => {
assert.htmlEqual(target.innerHTML, `
<p>a title: 42</p>
`);
});
}
};

@ -0,0 +1,7 @@
{#each items as item}
{#await item.data}
<p>{item.title}: loading...</p>
{:then result}
<p>{item.title}: {result}</p>
{/await}
{/each}
Loading…
Cancel
Save