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
691 stars 155 forks source link

Add `waitFor` support to async arrow function API #531

Open bendemboski opened 1 year ago

bendemboski commented 1 year ago

I am opening this PR to start a discussion. There is currently no way I can find to wrap async arrow function tasks in a test waiter a la waitFor from @ember/test-waiters. So this is a stab at adding support for that -- see the commit message for an explanation of this solution.

I haven't updated any documentation or anything because I want to see if this is a direction we want to pursue first.

A couple of alternatives I thought of:

  1. Figure out how to make the babel plugin smarter so it can recognize when the task function is wrapped in a "modifier function," e.g. myTask = task(waitFor(async () => { /* ... */ })); would produce { generator: waitFor(function*() { /* ... */ }) }. This seems sketchy because in the source code the modifier function would be called with an async function while in the transpiled code it would be called with a generator function. This happens to work for waitFor, but providing generic support for modifier functions like this would come with a pretty screwy caveat that they must support being passed generator functions even though they must be typed to accept async functions.
  2. Make the options interface more generic -- define a type/interface for these sorts of modifier functions like waitFor and then do something like myTask = task({ modifiers: [ waitFor ] }, async () => { /* ... */ });. This would allow us to type the modifier functions to accept a generator function without running into trouble because the un-transpiled source code would never invoke the modifier function. On the other hand, it complicates the syntax and it's not clear there will ever be a need for other modifier functions like this. I'm happy to explore this route if we prefer -- I don't think it would be much more work.
  3. Just say we no longer support wrapping tasks in test waiters this way, and tell users to either wrap each promise in a waitForPromise() call, or work with the @ember/test-waiters maintainers to try to devise some other easy way to wrap ember-concurrency tasks.

I'm very interested to hear folks' thoughts as my app relies heavily on @waitFor, and I really love the async arrow function syntax and want to move to it soon as I can figure out what to do about the @waitFors!

Related to #513