Skip to content

Commit

Permalink
Add ability to abort cancelled promise
Browse files Browse the repository at this point in the history
  • Loading branch information
Exelord committed May 12, 2020
1 parent c6457cd commit 003b7b1
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 9 deletions.
24 changes: 20 additions & 4 deletions addon/components/await/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,18 +140,34 @@ class AwaitComponent extends Component {
}

@task({ restartable: true, evented: true })
*promiseTask(promise, ...args) {
return yield isFunction(promise) ? promise(...args) : promise;
*promiseTask(value) {
const controller = new AbortController();
const promiseFn = isFunction(value) ? value : () => value;

try {
return yield promiseFn(controller);
} finally {
controller.abort();
}
}

@task({ drop: true })
*deferTask(value, args = []) {
const deferFn = isFunction(value) ? value : () => value;

return yield this.promiseTask.perform((controller) => deferFn(args, controller));
}

@action
run(...args) {
this.promiseTask.perform(this.args.defer, ...args);
if (isDefined(this.args.defer)) {
return this.deferTask.perform(this.args.defer, args);
}
}

@action
reload() {
this._resolvePromise();
return this._resolvePromise();
}

@action
Expand Down
4 changes: 2 additions & 2 deletions docs/api/arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ These can be passed to `<Await />` component.

## `promise`

> `Promise | function(): Promise`
> `Promise | function(controller: AbortController): Promise`
A Promise instance which has already started or a function that returns a promise Changing the value of `promise` will cancel any pending promise and listen to the new one. The promise function is automatically invoked during component construction. If `promise` is initially undefined, the Ember Await state will be `pending`.

> Note that `reload` will not do anything when `promise` has been passed as property not a function.
## `defer`

> `function(...args): Promise`
> `function(args: any[], controller: AbortController): Promise`
A function that returns a promise. This is invoked only by manually calling `run(...args)`. The `defer` is commonly used to send data to the server following a user action, such as submitting a form. You can use this in conjunction with `promise` to fill the form with existing data, then updating it on submit with `defer`.

Expand Down
1 change: 1 addition & 0 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ ember install ember-await
* Ember.js v3.16 or above
* Ember CLI v2.13 or above
* Node.js v10 or above
* Evergreen browsers (IE11 not supported)
8 changes: 5 additions & 3 deletions docs/guides/migrate-from-routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ We gonna create 3 files:

### PostsList component

Here we define `fetchPosts` which looks identically to previous `model()` hook. In this case it is a function, however it can be a getter or just a property.
Here we define `fetchPosts` which looks almost identically to previous `model()` hook. In this case it is a function, however it can be a getter or just a property.

In this case the `fetchPosts` recieves an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) which allows you (or the request maker) to watch when Ember Await has aborted the request. As we are using `fetch` we are passing the `signal` to it, so it can abort the request when needed. This will optimize your data fetching and ensure there is always one pending request at the time.

```js
// app/components/posts-list.js
Expand All @@ -93,8 +95,8 @@ import { action } from '@ember/object';

class PostsComponent extends Component {
@action
async fetchPosts() {
const response = await fetch('/posts');
async fetchPosts(abortController) {
const response = await fetch('/posts', { signal: abortController.signal });
return response.json();
}
}
Expand Down

0 comments on commit 003b7b1

Please sign in to comment.