machty / ember-concurrency

ember-concurrency is an Ember Addon that enables you to write concise, worry-free, cancelable, restartable, asynchronous tasks.
http://ember-concurrency.com
MIT License
689 stars 157 forks source link

feat: add helper to wrap a function in a task #322

Closed alexlafroscia closed 5 years ago

alexlafroscia commented 5 years ago

Would you be interested in a helper that, accepting a function, returns an action that wraps that function? This is a pattern that's come up in the application I maintain at work, where a component yields an async function.

I'm imagining something like this:

<SomeComponentThatYieldsAnAction as |someAction|>
  {{#let (action-to-task someAction) as |someTask|}}
    <button {{action (perform someTask)}}>
      {{if someTask.isRunning 'Running!' 'No running!'}}
    </button>
  {{/let}}
</SomeComponentThatYieldsAnAction>

If that's of interest, I'm happy to PR an implementation!

maxfierke commented 5 years ago

I guess the tricky bit with this might be around the ownership of the task. Assuming the helper is the owner/host object, how does that work with auto-cancellation or when the action changes? (I'm not sure exactly what the "lifecycle" of a helper is.)

buschtoens commented 5 years ago

A (class-based) helper lives as long as it is not unrendered. Changing any input positional or named param will call compute. I made use of this in ember-render-helpers.

alexlafroscia commented 5 years ago

Yeah, I don't see it being too different than the lifecycle with regard to a component.

Maybe this would be worth prototyping as a separate add-on (or permanently being something separate) to work out mechanics before potentially upstreaming to this package.

alexlafroscia commented 5 years ago

I cooked this up as a prototype of what I'm thinking. Doesn't handle any modifiers yet, but the mechanics are right, I think.

https://github.com/alexlafroscia/ember-concurrency-wrap-in-task

maxfierke commented 5 years ago

I like it! Are you thinking something like separate helpers for each of the modifiers? (e.g. restartable-task, etc.)

I would agree that this probably makes sense as a separate add-on, for now though.

alexlafroscia commented 5 years ago

Are you thinking something like separate helpers for each of the modifiers?

Yeah! I'd love for that to be an argument to the helper, but I'm not sure there is really a good way to achieve that. I'll play around with it, though!

I would agree that this probably makes sense as a separate add-on, for now though.

Cool; I'll close the issue for now!

alexlafroscia commented 5 years ago

I actually ended up able to support the task modifiers without separate helpers for each of them:

{{wrap-in-task (action this.someAction) type="drop" maxConcurrency=3}}