ember-stateful-promise v1.0.0
ember-stateful-promise
ember-concurrency is the go to solution in the Ember community for tracking async action state and many other tasks around async behaviour.
ember-stateful-promise seeks to simplify with native async/await instead of generators and expose a few flags on a promise object for you to use. Moreover, they are tracked! This library can be used if you simply need derived state your async functions and/or need a lightweight version of ember-concurrency.
Also ember-promise-helpers is another great library if you want to calculate state from your promises. ember-stateful-promise is different in that is seeks to provide derived state.
Lastly, if you already use ember-concurrency but rather author with async/await, ember-concurrency-async is available as a babel build time plugin. Again, you just need to weigh the tradeoffs (size, complexity) for your project.
API
Supports
- Derived state
- Debouncing async functions
- Cleanup of async functions wired up with
@ember/destroyable
isRunningisResolvedisErrorisCanceledperformCountcancel()// this.clickMe.cancel()
Usage
There are a few ways to use this addon. Likely, you only need the stateful-function decorator. However, if you need the lower level util, we make that available as StatefulPromise as well.
Decorator
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { statefulFunction } from 'ember-stateful-promise/decorators/stateful-function';
class MyComponent extends Component {
@statefulFunction
async clickMe() {
await fetch(url);
}
}<button
disabled={{if this.clickMe.isRunning "true"}}
{{on "click" this.clickMe}}>
Click
</button>
<p>(Clicked this many times - {{this.clickMe.performCount}})</p>Note - the default behaviour out of the box is to debounce the action. When clicked while a promise is outstanding, the first promise will be rejected and a new promise will be created.
To throttle the function, pass { throttle: true } to the decorator arguments.
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { statefulFunction } from 'ember-stateful-promise/decorators/stateful-function';
class MyComponent extends Component {
@statefulFunction({ throttle: true })
async clickMe() {
await fetch(url);
}
}@statefulFunction replaces @action while giving you all the features of this addon!
Stateful Promise
- Promise
interface
import { StatefulPromise } from 'ember-stateful-promise/utils/stateful-promise';
const promise = fetch(url);
let result = new StatefulPromise((resolveFn, rejectFn) => {
promise.then((data) => resolveFn(data)).catch((e) => rejectFn(e));
});
result.isRunning; // true
result.isResolved; // false
result.isError; // false
await result;
result.isRunning; // false
result.isResolved; // true
result.isError; // falsecreatemethod with destroyable
import { StatefulPromise } from 'ember-stateful-promise/utils/stateful-promise';
const promise = fetch(url);
let result = new StatefulPromise().create(this, promise);
result.isRunning; // true
result.isResolved; // false
result.isError; // false
await result;
result.isRunning; // false
result.isResolved; // true
result.isError; // falseimport { StatefulPromise } from 'ember-stateful-promise/utils/stateful-promise';
import { action } from '@ember/object';
class MyComponent extends Component {
@action
clickMe() {
const promise = fetch(url);
// Destroyable registered
let result = new StatefulPromise().create(this, (resolveFn, rejectFn) => {
promise.then((data) => resolveFn(data)).catch((e) => rejectFn(e));
});
// Component destroyed
// and then
try {
await result;
} catch (e) {
// WILL ERROR here!
}
}
}Compatibility
- Ember.js v3.20 or above
- Ember CLI v3.20 or above
- Node.js v12 or above
Installation
ember install ember-stateful-promiseContributing
See the Contributing guide for details.
License
This project is licensed under the MIT License.