Skip to content

Commit c2fca59

Browse files
committed
Expose TaskInstance state inside encapsulated tasks
While TaskInstance state was exposed externally via proxying, the proxy was not used internally making TaskInstance state impossible to access.
1 parent a7223c0 commit c2fca59

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

addon/-private/task.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ if (TRACKED_INITIAL_TASK_STATE) {
289289

290290
Object.assign(Task.prototype, TASKABLE_MIXIN);
291291

292+
const currentTaskInstanceSymbol = '__ec__encap_current_ti';
292293
export class EncapsulatedTask extends Task {
293294
constructor(options) {
294295
super(options);
@@ -297,15 +298,31 @@ export class EncapsulatedTask extends Task {
297298
this._encapsulatedTaskInstanceProxies = new WeakMap();
298299
}
299300

301+
_getEncapsulatedTaskClass() {
302+
let encapsulatedTaskImplClass = this._encapsulatedTaskImplClass;
303+
304+
if (!encapsulatedTaskImplClass) {
305+
encapsulatedTaskImplClass = EmberObject.extend(this.taskObj, {
306+
unknownProperty(key) {
307+
let currentInstance = this[currentTaskInstanceSymbol];
308+
return currentInstance ? currentInstance[key] : undefined;
309+
},
310+
});
311+
}
312+
313+
return encapsulatedTaskImplClass;
314+
}
315+
300316
_taskInstanceFactory(args, performType) {
301317
let owner = getOwner(this.context);
302-
let encapsulatedTaskImpl = EmberObject.extend(this.taskObj).create({
318+
let taskInstanceProxy;
319+
let encapsulatedTaskImpl = this._getEncapsulatedTaskClass().create({
303320
context: this.context,
304321
});
305322
setOwner(encapsulatedTaskImpl, owner);
306323

307324
let generatorFactory = () =>
308-
encapsulatedTaskImpl.perform.apply(encapsulatedTaskImpl, args);
325+
encapsulatedTaskImpl.perform.apply(taskInstanceProxy, args);
309326
let taskInstance = new TaskInstance({
310327
task: this,
311328
args,
@@ -317,10 +334,13 @@ export class EncapsulatedTask extends Task {
317334
performType,
318335
hasEnabledEvents: this.hasEnabledEvents,
319336
});
337+
encapsulatedTaskImpl[currentTaskInstanceSymbol] = taskInstance;
320338

321339
this._encapsulatedTaskStates.set(taskInstance, encapsulatedTaskImpl);
322340

323-
return this._wrappedEncapsulatedTaskInstance(taskInstance);
341+
taskInstanceProxy = this._wrappedEncapsulatedTaskInstance(taskInstance);
342+
343+
return taskInstanceProxy;
324344
}
325345

326346
_wrappedEncapsulatedTaskInstance(taskInstance) {

tests/unit/encapsulated-task-test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { run } from '@ember/runloop';
22
import RSVP from 'rsvp';
33
import EmberObject from '@ember/object';
4+
import { reads } from '@ember/object/computed';
45
import { task } from 'ember-concurrency';
56
import { module, test } from 'qunit';
67
import { decoratorTest } from '../helpers/helpers';
@@ -85,6 +86,31 @@ module('Unit: EncapsulatedTask', function () {
8586
assert.equal(value, 'pickle');
8687
});
8788

89+
test('encapsulated tasks can access task instance context', async function (assert) {
90+
assert.expect(2);
91+
92+
let defer;
93+
let Obj = EmberObject.extend({
94+
myTask: task({
95+
amIRunning: reads('isRunning'),
96+
97+
*perform() {
98+
defer = RSVP.defer();
99+
yield defer.promise;
100+
return 'blah';
101+
},
102+
}),
103+
});
104+
105+
let obj = Obj.create();
106+
const taskInstance = obj.get('myTask').perform();
107+
assert.equal(taskInstance.amIRunning, true);
108+
109+
defer.resolve();
110+
await taskInstance;
111+
assert.equal(taskInstance.amIRunning, false);
112+
});
113+
88114
decoratorTest(
89115
'encapsulated tasks work with native ES classes and decorators',
90116
function (assert) {

0 commit comments

Comments
 (0)