Skip to content

Commit

Permalink
Rename async() to until()
Browse files Browse the repository at this point in the history
  • Loading branch information
justinfagnani committed Nov 29, 2018
1 parent 6e5868f commit 86e4768
Show file tree
Hide file tree
Showing 8 changed files with 379 additions and 483 deletions.
8 changes: 4 additions & 4 deletions docs/_guide/03-template-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ lit-html includes a few built-in directives.
* [`repeat`](#repeat)
* [`ifDefined`](#ifdefined)
* [`guard`](#guard)
* [`async`](#async)
* [`until`](#until)
* [`asyncAppend` and `asyncReplace`](#asyncappend-and-asyncreplace)

**Directives may change.** The exact list of directives included with lit-html, and the API of the directives may be subject to change before lit-html 1.0 is released.
Expand Down Expand Up @@ -327,9 +327,9 @@ const template = html`

In this case, items are mapped over only when the array reference changes.

### async
### until

`async(...values)`
`until(...values)`

Renders one of a series of values, including Promises, to a Part.

Expand All @@ -347,7 +347,7 @@ resolves.
Example:

```javascript
import { async } from 'lit-html/directives/async.js';
import { until } from 'lit-html/directives/until.js';

const content = fetch('./content.txt').then(r => r.text());

Expand Down
2 changes: 1 addition & 1 deletion docs/_guide/04-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ For more information on JavaScript modules:

* [Using JavaScript Modules on the Web](https://developers.google.com/web/fundamentals/primers/modules) on Web Fundementals.

* [import statement reference page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) on MDN.
* [import statement reference page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) on MDN.
97 changes: 0 additions & 97 deletions src/directives/async.ts

This file was deleted.

88 changes: 79 additions & 9 deletions src/directives/until.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,86 @@
* http://polymer.github.io/PATENTS.txt
*/

import {isPrimitive} from '../lib/parts.js';
import {directive, Part} from '../lit-html.js';

interface AsyncState {
/**
* The last rendered index of a call to until(). A value only renders if its
* index is less than the `lastRenderedIndex`.
*/
lastRenderedIndex?: number;

values: unknown[];
}

const _state = new WeakMap<Part, AsyncState>();

/**
* @deprecated Use `async` from async.js instead
* Renders one of a series of values, including Promises, to a Part.
*
* Values are rendered in priority order, with the first argument having the
* highest priority and the last argument having the lowest priority. If a
* value is a Promise, low-priority values will be rendered until it resolves.
*
* The priority of values can be used to create placeholder content for async
* data. For example, a Promise with pending content can be the first,
* highest-priority, argument, and a non_promise loading indicator template can
* be used as the second, lower-priority, argument. The loading indicator will
* render immediately, and the primary content will render when the Promise
* resolves.
*
* Example:
*
* const content = fetch('./content.txt').then(r => r.text());
* html`${until(content, html`<span>Loading...</span>`)}`
*/
import {noChange} from '../lit-html.js';
export const until = directive((...args: any[]) => (part: Part) => {
let state = _state.get(part)!;
if (state === undefined) {
state = {
values: [],
};
_state.set(part, state);
}
const previousValues = state.values;
let changedSinceLastRender = false;
state.values = args;

import {async} from './async.js';
for (let i = 0; i < args.length; i++) {
const value = args[i];

export const until =
(promise: Promise<any>, defaultContent: any = noChange) => {
console.warn(
'until() is deprecated, please use async() from directives/async.js');
return async(promise, defaultContent);
};
// If we've seen this value before, we've already handled it.
if (value === previousValues[i] && !changedSinceLastRender) {
continue;
}
changedSinceLastRender = true;

// Render non-Promise values immediately
if (isPrimitive(value) || typeof value.then !== 'function') {
part.setValue(value);
state.lastRenderedIndex = i;
// Since a lower-priority value will never overwrite a higher-priority
// synchronous value, we can stop processsing now.
break;
}

// We have a Promise that we haven't seen before, so priorities may have
// changed. Forget what we rendered before.
state.lastRenderedIndex = undefined;

Promise.resolve(value).then((resolvedValue: unknown) => {
const index = state.values.indexOf(value);
// If state.values doesn't contain the value, we've re-rendered without
// the value, so don't render it. Then, only render if the value is
// higher-priority than what's already been rendered.
if (index > -1 &&
(state.lastRenderedIndex === undefined ||
index < state.lastRenderedIndex)) {
state.lastRenderedIndex = index;
part.setValue(resolvedValue);
part.commit();
}
});
}
});
Loading

0 comments on commit 86e4768

Please sign in to comment.