Comments (20)
We had a meeting today with the blaze-async-workgroup and we came up with the first task / concept for blaze.
Daniel D or @sebastianspiller will submit the PR with the helpers being async and we will tackle next the following(idealized by @radekmie):
for the tasks, what we have is:
- Add
#letAwait
to Blaze DSL with simple usage(just unwrap) (PR with tests and such); - Work on having pending and error states for
#letAwait
- Work in the building block such as
{{await something}}
or{{await s.foo}}
- Work on having pending and error states for
await
keyword, maybe a #await block for this
In these tasks, the latter three can be parallelized, but we need the letAwait building block
from blaze.
Is there a reason it is named #letAwait instead of #await?
I just wanted to make it stay in-align with #let
. await
(or #await
, but it's not a block) is also a good name.
[...] What is the plan to avoid this performance problem in blaze?
There's non... Yet. I've spent on it about an hour now, just making sure what is possible syntax-wise (including parser). Maybe a Suspense-like approach from React would work? That is, schedule updates "once in a while" and adjust DOM only if the update won't make it.
But then again, it's a separate issue - Minimongo queries (or at least some of them) could rely on observe
, just like useFind
in React integration (source).
from blaze.
Agreed!
I'm thinking that both Meteor and Blaze v3 will be all about Fibers and Promises. I think things will move towards the same pattern of development and support as Node has.
from blaze.
OK, I think this is something that we should include as a main feature in Blaze 2.7.
Sadly I'm currently unable to in any way participate in building this functionality.
from blaze.
Maybe we can first collect what all needs to be supported, especially in combination with all new changes by Meteor 2.8+
from blaze.
Regarding asynchronous management, I think it is also useful to consider hooks: created, rendered and destroyed. Now callbacks are synchronous but we will often have asynchronous calls within them.
from blaze.
FYI: I tried implementing the Tracker context logic, currentComputation, with zone.js but it doesn't not intercept the native promises (async/await). Used with legacy version of the bundle it works but feels like going backwards. Does anyone know of alternative packages to do this?
from blaze.
My point of view regarding handling async code would be divided in two parts. Not sure if it makes 100% sense but it could be a way to implement this.
First we need to handle promises/promise-like functions. We could do something like svelte, as I commented in the other pr or other ways.
{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
in blaze could be like:
<template name="example">
{{#with asyncTest}}
{{#await this.foo}}
<p>...waiting</p>
{{:then bar}}
<p>result: {bar}</p>
{{:catch error}}
<p style="color: red">{error.message}</p>
{{/await }}
{{/with}}
</template>
Then or in parallel, we would need to handle how to make Meteor/tracker
async / accept async dependencies. As for today it has its limitations regarding async
from blaze.
The idea is not bad, but Tracker has to support asynchronous processes and to do that I think it will have to track calls, a bit like Angular and Dart. Your Blaze example can already be done with reactive variables and a heavy memory overhead, but if we have no way to intercept changes to an asynchronous object we lose reactivity. Assume the following pseudo-example
const vars = new ReactiveVar();
Tracker.autorun(async () => {
const user = await Meteor.userAsync();
const a = await coll.find({userCode: user.profile.companyCode).fetchAsync();
const b = await coll2.find({extCode: a.extCode).fetchAsync();
vars.set(b):
})
Changes coming from the DDP are not intercepted because on the first await the autorun loses context. Losing the native Meteor reactivity has a big impact.
My opinion is to keep Minimongo client-side synchronous at least until the Tracker problem is solved.
from blaze.
The concept of synchronous Minimongo access is something I suggested also in the main Meteor Async PR discussion: async focus can go first to Meteor.call use cases. It would reduce impact to smaller set of Tracker async cases one has to deal with.
In my opinion, finding a solution for the predictability of the onCreated, onRendered, onDestroyed sequence, and the concept of helpers kicking in after onCreated only, is a more impacting challenge to address.
If one could be sure that a OnCreatedAsync hook would be waited for before the OnRendered or OnRenderedAsync hook is called, that could make it easy to refactor these hooks to using async back end calls.
The next thing could be await-ed event hooks, because these are also the trivial places to find async back end calls. Helpers are conceptually already more or less async since they fire once and by reactiveness.
from blaze.
Changes coming from the DDP are not intercepted because on the first await the autorun loses context. Losing the native Meteor reactivity has a big impact.
@klablink I observed this (indirectly) by turning a helper into an async helper, can you elaborate why the context is lost after the first await ?
My opinion is to keep Minimongo client-side synchronous at least until the Tracker problem is solved.
Agreed !
from blaze.
@klablink I observed this (indirectly) by turning a helper into an async helper, can you elaborate why the context is lost after the first await?
Hi @polygonwood
Blaze's reactivity is based on Meteor's Tracker package. This uses a global variable, currentComputation, to map the relationship between a function to be called when a certain reactive variable changes and/or a minimon search. Now, if the process becomes asynchronous, on the first await the currentComputation will lose the reference for the rest of the calls.
For better understanding I will insert the code extract of Current Tracker:
_compute() {
this.invalidated = false;
var previous = Tracker.currentComputation;
setCurrentComputation(this);
var previousInCompute = inCompute;
inCompute = true;
try {
withNoYieldsAllowed(this._func)(this);
} finally {
setCurrentComputation(previous);
inCompute = previousInCompute;
}
}
As you can see, this._func
must be synchronous to work in the current context, otherwise setCurrentComputation(previous)
is executed immediately, losing context.
There has been much discussion on the subject (see this PR), and it seems that in Meteor version 2.10 there will be the possibility of invoking asynchronous functions by passing the tracker context. This will mean a major change for Blaze and many client packages.
from blaze.
from blaze.
Hello from Germany
I saw Tracker.withComputation in 2.10 and had a look on blaze, how hard can it be to make it work?
I could quickly asynchronize some functions and I could write some self resolving helpers in a demo project, I was enthusiastic about it and wanted more
At the moment, async pops up everywhere, what I don't want because then the whole API will be async, too, in future. I have problems now, that the Blaze.View is missing.
I will keep on and just wanted to mention, that someone's working on it and want to know, if someone else gives it a try at the moment. Simply putting async everywhere doesn't seem the solution and I may think of another approach.
Regards 💯
from blaze.
Probably, to make this happen, you will need to use .then
other than async
, IMO I would make this a two-step approach, one keyword like withSync to get the promise and then unwarp it, that is the second step, where it could resolve to a value that can be stringified and in sync. Or it can resolve to an error that can also be stringified.
It would look a lot like svelte but is the way with the best DX
from blaze.
Hi, I made some progress, talked to @jankapunkt and want to share a code snippet:
view.js : 350
I added a reactive var to Blaze.View and in the Blaze._materializeView function, I did this:
let htmljs = view._render()
htmljs = view.promiseReactiveVar.get() ? view.promiseReactiveVar.get() : htmljs
if (htmljs instanceof Promise) {
htmljs.then(val => {
view.promiseReactiveVar.set(val)
})
return
}
With this trick, htmljs will trigger an autorun as soon as its Promise resolves. So I could work inside Spacbars like Spacebars.dot and make them async, so that htmljs can handle the Promises.
I ran the test suite and only 2 failed, but they also fail since 2.10, so my next steps are:
- Work with new ES6 updated PRs
- Update blaze test-app
- Write Tests for async stuff
Problems are, that I couldn't manage to make this works so that Attributes
{{asyncHelper.text}} or {{asyncCollectionHelper.method.text}}
I'll keep you uptodate
from blaze.
Hey @sebastianspiller, how is it going? Maybe you could share your changes so that we may check these tests as well.
By having a PR based on your fork, we could be helping on another front, such as the testing and documenting
from blaze.
I like the syntax for this. Is there a reason it is named #letAwait
instead of #await
?
One problem with svelte and its await
blocks is every time the promise changes, it removes the DOM for the await block, creates the DOM for the pending block, and then when the promise resolves removes the DOM for the pending block and recreates the DOM for the await block. In most situations that is fine, but for minimonogo queries with results that frequently change or that have DOM that is expensive to render, this would be very inefficient since every time the results change it creates a new promise that immediately resolves. For this and other reasons, I'm considering recommending svelte apps not use await blocks for queries.
What is the plan to avoid this performance problem in blaze?
from blaze.
#409 should be linked here.
from blaze.
I think with #412 we can close this one @jankapunkt ?
from blaze.
Related Issues (20)
- Handlebars syntax is not bad at all, we can make it faster than React, Vue, or Svelte HOT 5
- small issue with parsing html comments inside Blaze templates HOT 3
- ReferenceError: SpacebarsCompiler is not defined HOT 1
- Help developers by indicating undefined data in debug mode
- Move codebase to ES6 HOT 15
- spacebars-tests packages still uses removed code
- Blaze.remove() destroys DOM before calling onDestroyed() HOT 8
- Error handling, callbacks and DOMRange HOT 9
- Errors in onCreated callback cause a complete stop for rendering further Templates
- Bootstrap select picker is not correctly removed / disposed during Template descruction HOT 6
- Add benchmarks to tests
- SSR is broken in 2.6.0 HOT 4
- Add ts types HOT 3
- Blaze compile errors completely silent if imported HOT 12
- Be able to have more contentBlock in template HOT 1
- Non-primitives not fully reactive in 2.7
- Complete GitHub community standards HOT 7
- CI/CD for documentaiton
- observe-sequence has a bug when _ids have a period HOT 11
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blaze.