-
Notifications
You must be signed in to change notification settings - Fork 317
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds performUpdate
and defers update
until connection
#368
Conversation
Fixes #290. The previous private `_validate` method has been made protected and named `performUpdate`. It's all now possible to return a promise from this method and doing so will block the update's completion until the promise is resolved. This allows control over the timing of update and integration with schedulers. Fixes #258. Updates are now deferred until element connection. This ensures that microtask checkpoints that may occur during element construction do not generate errors or cause extra update cycles.
src/lib/updating-element.ts
Outdated
* to schedule updates to occur just before the next frame: | ||
* | ||
* ``` | ||
* protected async scheduleUpdate(): Promise<unknown> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be performUpdate() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, changed.
* } | ||
* ``` | ||
*/ | ||
protected performUpdate(): void|Promise<unknown> { | ||
// Mixin instance properties once, if they exist. | ||
if (this._instanceProperties) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be moved to the connectedCallback
and take this check out of the every-render path?
src/lib/updating-element.ts
Outdated
} | ||
return this._invalidate(); | ||
if (!this._hasRequestedUpdate && shouldRequestUpdate) { | ||
this._setupUpdate(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming: is _enqueueUpdate
better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
await previousUpdatePromise; | ||
// Make sure the element has connected before updating. | ||
if (!this._hasConnected) { | ||
await new Promise((res) => this._hasConnectedResolver = res); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems unfortunate to need to introduce another promise to synchronize a pending update with connected, but I get that it is needed to keep the updateComplete
promise pending to allow someone to await el.updateComplete
before it is connected. I don't have a better idea, other than saving the _updatePromise
resolver and letting connected's call to requestUpdate
use the same promise. Not sure that's any better.
Would it be too weird to just document that the pending update system isn't ready until first connected, so updateComplete
shouldn't be awaited until the element is connected? That would allow you to just bail in requestUpdate
(since you'll always come back in when connected).
If you don't like either of those suggestions this code is fine, not that big of a deal. Just somehow feels more complicated than it should be and wanted to brainstorm a little.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Acknowledged, but think it makes sense to keep as is.
Fixes #290. The previous private
_validate
method has been made protected and namedperformUpdate
. It's all now possible to return a promise from this method and doing so will block the update's completion until the promise is resolved. This allows control over the timing of update and integration with schedulers.Fixes #258. Updates are now deferred until element connection. This ensures that microtask checkpoints that may occur during element construction do not generate errors or cause extra update cycles.