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
690 stars 157 forks source link

Document interface of the host object expected by EC #360

Open Herriau opened 4 years ago

Herriau commented 4 years ago

Unless I missed something, there is no documentation of the interface that is expected from the host object. Here is the best I could find so far:

ember-concurrency tasks are scoped to the lifetime of the object they live on, so if that object is destroyed, all of the tasks attached to it are canceled. This is very convenient when writing tasks on object with finite lifetimes, like Components, but certain Ember objects, like Routes (and Controllers), are never actually destroyed. Even if you can't rely on object destruction to cancel a task, ember-concurrency makes it easy to run tasks between lifecycle events other than init and destroy. (http://ember-concurrency.com/docs/examples/route-tasks/1)

Most of the time I use EC tasks within Ember.Component or Ember.Service sub-classes, but occasionally I find myself wanting to use it in vanilla classes (that do not expose the Ember.Object or Ember.Evented interfaces), and it's not clear what EC expects of the host object. I understand that among other things EC needs to be able to tell when the host object gets destroyed, but how it monitors the destruction of the host object is a mystery.

More and more, the Ember leadership team is advocating against extending EmberObject so it would seem opportune for EC to document usage in a more vanilla context. It'd be great if the interface expected of the host object were documented in the API doc, or better yet formalized through a rigorously typed task() decorator in a TS declaration file.

maxfierke commented 4 years ago

For the most part, ember-concurrency just needs to know about willDestroy, which is implemented by all Ember Object-derived objects (and also Component from @glimmer/component).

For using waitForEvent, the object needs to implement on and off, or one, or addEventListener and removeEventListener. This is documented in the API for waitForEvent.

For using the evented() modifier, it is expected that it includes Ember.Evented (though just having a trigger method with the same API would suffice too)

ember-concurrency <= 1.x is inextricably linked to the Ember Object model, and so the reason for these not being more documented for non-EmberObject use cases is primarily because historically it has been primarily focused on Components and it wasn't possible to use with POJOs (or at the very least things would behave oddly). However, in recent Ember releases (specifically since 3.10) this isn't so much the case and it is usable, for example with Glimmer components. Once #357 is merged, we could potentially add some typing for the host object to those type definitions too.

ember-concurrency 2.x (still WIP, but there's an alpha release) uses a core that's not linked to Ember at all, and will allow us to work out the non EmberObject use-case going forward, and when that's ready there will likely be more documentation about use in this context.

Herriau commented 4 years ago

Thank you @maxfierke this is very useful!

chancancode commented 4 years ago

We should probably look into transitioning into https://github.com/ember-polyfills/ember-destroyable-polyfill instead of relying on willDestroy

maxfierke commented 4 years ago

oh nice, I didn't realize that RFC had been merged. I'll take a look at that later.