Implemented async bindings in #let
.
#412
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In this pull request, I made
#let
handlePromise
s. It supersedes #409 as it solves the same problem, but there's no#letAwait
needed.How it works
All Blaze
View
s store a binding mapping (_scopeBindings
), where#each
stores the@index
variable and#let
stores the locally scoped variables. Each binding is not a value but rather aReactiveVar
that is updated when needed.In this PR, these
ReactiveVar
s no longer store the value but rather aBinding
object. Type-wise, it's eitherundefined
(pending),{ error }
(rejected), or{ value }
(resolved). Synchronous values are immediately resolved (i.e.,{ value }
is used). The other states are reserved for asynchronous bindings (i.e., values wrapped withPromise
s).That means the following template:
Works with both synchronous and asynchronous
getName
:Async state
As the unwrapping of
Promise
s is not synchronous, all asynchronous values and helpers will start in a pending state. In such cases, the resolved value is alwaysundefined
. That means the template above will showHi, !
at first for both asynchronous examples. Similarly, a rejection will make the valueundefined
.But there are cases where we'd like to know whether the operation is still pending or if it failed. To make it possible, there are three new global helpers:
@pending
, which checks whether any of the given bindings is still pending.@rejected
, which checks whether any of the given bindings has rejected.@resolved
, which checks whether any of the given bindings has resolved.The usage looks as follows:
All of them accept a list of names to check. Passing no arguments is the same as passing all bindings from the inner-most
#let
:Given the following helpers:
We'll see three states:
Backward compatibility
As long as you never returned
Promise
s from your helpers used in#let
blocks, everything should work as before. If you did, these will be unwrapped. Note that direct usage of asynchronous helpers (e.g.,{{counterAsync}}
) won't work and will render[object Promise]
instead.TODO
@pending
/@rejected
/@resolved
should check for any or all bindings.@pending
should betrue
when a resolved helper is recalculated. Another option is to remove the value/error when restarted. In other words: is pending a state or a flag (the latter would work just like SWR).false
for now (i.e., once resolved,@pending
will never turn totrue
ever again), document this behavior, and mark it as a subject it change.A detailed example used for testing