Previous: Encapsulated Tasks
Next: Task Modifiers
ember-concurrency implements a number of lifecycle events that allow
for a host object to react to various changes in task instance lifecycle.
Using lifecycle hooks allows for adding things like instrumentation to tasks
or for separating and reusing error handling code across different tasks.
Using the evented
modifier will enable tasks to fire lifecycle
events on their host objects.
In the below example, we refactor the
AJAX throttling example to use
task events for logging of the ajaxTask
's state changes, instead
of doing it manually in the looping task itself.
const COLORS = [ '#0000FF', '#8A2BE2', '#A52A2A', '#DC143C', '#20B2AA', '#FF1493', '#228B22', '#DAA520', ]; function loopingAjaxTask(id) { return function* () { while (true) { try { yield this.ajaxTask.perform(id); } catch (e) { // Ignoring AJAX failures because we're being naughty. } yield timeout(2000); } }; } export default class TaskLifecycleEventsExample extends Component { tagName = ''; logs = []; constructor() { super(...arguments); addListener(this, 'ajaxTask:started', this, this.ajaxTaskStarted); addListener(this, 'ajaxTask:succeeded', this, this.ajaxTaskSucceeded); addListener(this, 'ajaxTask:errored', this, this.ajaxTaskErrored); } willDestroy() { super.willDestroy(...arguments); removeListener(this, 'ajaxTask:started', this, this.ajaxTaskStarted); removeListener(this, 'ajaxTask:succeeded', this, this.ajaxTaskSucceeded); removeListener(this, 'ajaxTask:errored', this, this.ajaxTaskErrored); } @task({ enqueue: true, maxConcurrency: 3, evented: true }) *ajaxTask() { // simulate slow AJAX const ms = 2000 + 2000 * Math.random(); yield timeout(ms); if (parseInt(ms) % 7 === 0) { throw new Error('Unexpected matrix glitch'); } return {}; } ajaxTaskStarted(taskInstance) { const [id] = taskInstance.args; this.log(COLORS[id], `Task ${id}: making AJAX request`); } ajaxTaskSucceeded(taskInstance) { const [id] = taskInstance.args; this.log(COLORS[id], `Task ${id}: AJAX done`); } ajaxTaskErrored(taskInstance, error) { const [id] = taskInstance.args; this.log( COLORS[id], `Task ${id}: AJAX failed because of '${error.message}'` ); } @task({ on: 'init' }) task0 = loopingAjaxTask(0); @task({ on: 'init' }) task1 = loopingAjaxTask(1); @task({ on: 'init' }) task2 = loopingAjaxTask(2); @task({ on: 'init' }) task3 = loopingAjaxTask(3); @task({ on: 'init' }) task4 = loopingAjaxTask(4); @task({ on: 'init' }) task5 = loopingAjaxTask(5); @task({ on: 'init' }) task6 = loopingAjaxTask(6); @task({ on: 'init' }) task7 = loopingAjaxTask(7); log(color, message) { let logs = this.logs; logs.push({ color, message }); this.set('logs', logs.slice(-7)); } }
Previous: Encapsulated Tasks
Next: Task Modifiers