Skip to content
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

Support promises/async at a template level #3168

Closed
PaulMaly opened this issue Dec 26, 2017 · 6 comments
Closed

Support promises/async at a template level #3168

PaulMaly opened this issue Dec 26, 2017 · 6 comments

Comments

@PaulMaly
Copy link

I found this issue: #1961
Seems, @Rich-Harris already changed his mind about this: https://svelte.technology/guide#await-blocks

I already tried {{#await /}} in Svelte and it's very cool. Perhaps we could add exactly same expression to Ractive?

p/s I know about Promise adaptor, moreover I make more in this direction in my "ractive-app" module, but "native" support will be very-very awesome!

@fskreuz
Copy link
Contributor

fskreuz commented Dec 26, 2017

Consider this: I happen to work with the promise adaptor while refactoring things. The code is just over a dozen lines before processing:

export default {
  filter: function (object) {
    return object != null && typeof object.then === 'function'
  },
  wrap: function (instance, object, keypath, prefix) {
    let removed = false
    const get = () => null
    const set = () => {}
    const reset = () => false
    const teardown = () => { removed = true }
    const setter = result => { removed ? void 0 : instance.set(keypath, result) }
    object.then(setter, setter)
    return { get, set, reset, teardown }
  }
}

Usage practically requires zero modification.

const instance = Ractive({
  template: '<p>{{ value }}</p>',
  data: { value: promise },
  adapt: [ Adaptor ]
})

Now if this were to be implemented natively, this would touch several parts of the core code. This would require updating the parser to consume the new syntax, the above logic integrated in the model code, a battery of tests. And since it's a template syntax change, templates would need a version bump which would affect tools like rcu (which is already behind in terms of maintenance, currently working on that as well).

Also, consider the fact that Svelte generates optimal JS. It only creates code when you tell it to. On the other hand, Ractive is a runtime library - all of Ractive is loaded regardless if its used or not. With an adaptor, you can just opt not to add it. But if it's native, it will be there regardless of use.

Not saying it's not possible, I'm totally cool with the idea (async components already uses a similar mechanism) and it's just a matter of scheduling and having the other tools keep up. But the gains over the cost is very minimal in my opinion.

@PaulMaly
Copy link
Author

@fskreuz Thank you for the code snippet, but could you please read my p/s section? ;-)

But if it's native, it will be there regardless of use.

I believe there is not project with Ractive without async operations. That's why I think it's a major feature.

@evs-chris
Copy link
Contributor

Here's a macro that implements awaiting.

It's not quite as built-in feeling as a new block-level constuct, but there's also no additional parser overhead required for the special inner-block interpolators (like {{else}}), which aren't exactly cheap to process. There are a few questions around how this sort of thing should behave either way (and the svelte docs seem to be mia now):

  1. When the promise resolves, is the success block run with the value as context?
  2. Should the error object come through somehow for the error block?
  3. What should happen should the promise not be then-able?
  4. Should the block allow changing the promise that it is based on or should it be a one-time thing?
  5. Should it try to handle already-resolved promises by scheduling the pending setup with a setTimeout?

Note that it looks like this exposes a bug in macros, wherein the macro is not notified on subsequent attribute updates.

@PaulMaly
Copy link
Author

PaulMaly commented Jan 4, 2018

@evs-chris I think Svelte has great implementation of this.

@evs-chris
Copy link
Contributor

Looks like the svelte docs now have the await block section for me, so I got curious what the ractive implementation would look like. If you check out the await branch you'll see it ends up adding about 100 loc after consolidating some of the else/elseif code.

I also adjusted the await macro to act the same way as the await branch and threw the matching template that will work in the await branch below it for comparison. I'm on the fence as to which I like more... the await block stands out a bit more, but it's also not exactly a cheap implementation. The ergonomics on the macro are about the same, and it doesn't add any weight to core.

@PaulMaly
Copy link
Author

Thanks! 🥇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants