in ember-concurrency
the extra setting of error
is a work around to prevent thrown exceptions from bubbling up to Ember's onerror
(since it is meant to be handled in the template). There is a feature request to handle this better.
An alternative community de facto standard is an addon called ember-concurrency that makes a lot of the promise confusion go away.
It can be installed with the command ember install ember-concurrency
.
try
/ catch
/ finally
blocks to manage asynchronous assignment, exceptions, and cleanup.willDestroy
event, avoiding errors setting values on destroyed objects (e.g. after a timer)ember install ember-concurrency
import Ember from 'ember';
import { task, timeout } from 'ember-concurrency';
const { Component, set } = Ember;
export default Component.extend({
myTask: task(function * () {
set(this, 'error', null);
try {
yield timeout(2000);
return 'Foobar';
} catch (err) {
set(this, 'error', error);
}
}).keepLatest()
});
{{#if myTask.isIdle}}
<button onclick={{perform myTask}}>
Start Task
</button>
{{else}}
Loading…
{{/if}}
{{#if myTask.last.value}}
Done. {{myTask.last.value}}
{{/if}}
{{#if error}}
Something went wrong. {{error}}
{{/if}}
Ember comes with a built in helper that will provide computed properties for the status of an asynchronous task.
Ember.Object
and cannot be applied to an Ember.Component
directly.content
value.import Ember from 'ember';
const {
Component, PromiseProxyMixin, get, set, computed,
isPresent, run, RSVP: { Promise }
} = Ember;
const MyPromiseProxy = Ember.Object.extend(PromiseProxyMixin);
export default Component({
myProxy: computed('promise', {
get() {
const promise = get(this, 'promise');
return isPresent(promise) ? MyPromiseProxy.create({promise}) : null;
}
}),
actions: {
performTask() {
const fakeTask = new Promise((resolve) => {
run.later(resolve, 'Foobar', 2000);
});
set(this, 'promise', fakeTask);
}
}
});
{{#if myProxy.isPending}}
Loading…
{{else}}
<button onclick={{action "performTask"}}>
Start Task
</button>
{{/if}}
{{#if myProxy.isFulfilled}}
Done. {{myProxy.content}}
{{/if}}
{{#if myProxy.isRejected}}
Something went wrong. {{myProxy.reason}}
{{/if}}