diff --git a/src/async/Task.ts b/src/async/Task.ts index 9bae2642..6b981f17 100644 --- a/src/async/Task.ts +++ b/src/async/Task.ts @@ -1,7 +1,7 @@ import { Thenable } from '@dojo/shim/interfaces'; import { Executor } from '@dojo/shim/Promise'; import ExtensiblePromise, { ListOfPromises, DictionaryOfPromises } from './ExtensiblePromise'; -import { Iterable } from '@dojo/shim/iterator'; +import { Iterable, forOf, isIterable, isArrayLike } from '@dojo/shim/iterator'; /** * Describe the internal state of a task. @@ -72,7 +72,28 @@ export default class Task extends ExtensiblePromise { static all(iterable: T | Thenable): Task; static all(iterable: ListOfPromises): Task; static all(iterable: DictionaryOfPromises | ListOfPromises): Task { - return > super.all(iterable); + return new Task((resolve, reject) => { + super.all(iterable).then( resolve, reject); + }, () => { + if (isIterable(iterable) || isArrayLike(iterable)) { + forOf(iterable, (promiseLike: any) => { + if (isTask(promiseLike)) { + promiseLike.cancel(); + } + }); + } + else { + const promiseKeys = Object.keys(iterable); + + promiseKeys.forEach((key: any) => { + const promiseLike = iterable[ key ]; + + if (isTask(promiseLike)) { + promiseLike.cancel(); + } + }); + } + }); } /** diff --git a/tests/unit/async/Task.ts b/tests/unit/async/Task.ts index 9a36f424..27527d04 100644 --- a/tests/unit/async/Task.ts +++ b/tests/unit/async/Task.ts @@ -383,6 +383,46 @@ function addPromiseTests(suite: any, Promise: any) { Promise.all(iterable).then(dfd.callback(function (value: number[]) { assert.notStrictEqual(value, iterable); })); + }, + + 'cancelable': { + 'isIterable': function (this: any) { + let pending: any[] = []; + + for (let i = 0; i < 3; i++) { + pending[i] = new Promise(function () {}); + } + + let tasks = Promise.all(pending); + + tasks.cancel(); + + tasks.then(() => { + pending.forEach((task) => { + assert.strictEqual(task.state, State.Canceled, 'Task should have Canceled state'); + }); + }); + }, + 'isObject': function (this: any) { + let pending = {}; + + for (let i = 0; i < 3; i++) { + pending[i] = new Promise(function () {}); + } + + let tasks = Promise.all(pending); + + tasks.cancel(); + + tasks.then(() => { + let keys = Object.keys(pending); + + keys.forEach((key) => { + let task = pending[key]; + assert.strictEqual(task.state, State.Canceled, 'Task should have Canceled state'); + }); + }); + } } };