Skip to content

Instantly share code, notes, and snippets.



Last active Jun 30, 2016
What would you like to do?
Abort your promises!
const abortable = promiseMaker => (...args) => {
let aborted = false;
const promise = new Promise((resolve, reject) => {
const resolveIfNotAborted = resolution => {
if (aborted) {
reject(Object.assign(Error('Promise Aborted'), {code: 'PROMISE_ABORTED'}));
promiseMaker(...args).then(resolveIfNotAborted, reject);
promise.abort = () => {
aborted = true;
return promise;
export default abortable;
import abortable from './abortable';
const names = ['John', 'Mary', 'William', 'Helen', 'James', 'Dorothy', 'Robert', 'Margaret', 'Joseph', 'Ruth', 'George', 'Anna', 'Charles', 'Mildred', 'Edward', 'Elizabeth', 'Frank', 'Frances', 'Walter', 'Marie', 'Thomas', 'Evelyn', 'Henry', 'Alice', 'Paul', 'Florence', 'Harold', 'Virginia', 'Albert', 'Rose', 'Raymond', 'Lillian', 'Richard', 'Louise', 'Arthur', 'Catherine', 'Harry', 'Edna', 'Louis', 'Gladys', 'Ralph', 'Ethel', 'Clarence', 'Irene', 'Donald', 'Josephine', 'Carl', 'Ruby', 'Willie', 'Grace', 'Howard', 'Thelma', 'Jack', 'Martha', 'Fred', 'Eleanor', 'David', 'Hazel', 'Kenneth', 'Lucille', 'Francis', 'Edith', 'Roy', 'Gertrude', 'Earl', 'Annie', 'Joe', 'Pauline', 'Samuel', 'Esther', 'Lawrence', 'Doris', 'Anthony', 'Clara', 'Ernest', 'Beatrice', 'Stanley', 'Emma', 'Michael', 'Ann', 'Alfred', 'Bertha', 'Herbert', 'Julia', 'Eugene', 'Bernice', 'Andrew', 'Agnes', 'Leonard', 'Marjorie', 'Elmer', 'Elsie', 'Leo', 'Sarah', 'Peter', 'Katherine', 'Russell', 'Ida', 'Bernard', 'Marion', 'Herman', 'Lois', 'Frederick', 'Eva', 'Edwin', 'Anne', 'Norman', 'Jean', 'Daniel', 'Bessie', 'Chester', 'Pearl', 'Lester', 'Viola', 'Floyd', 'Mabel', 'Melvin', 'Laura', 'Leroy', 'Myrtle', 'Vincent', 'Nellie', 'Clifford', 'Betty', 'Clyde', 'Kathryn', 'Theodore', 'Jessie', 'Charlie', 'Stella', 'Lloyd', 'Willie', 'Sam', 'Minnie', 'Philip', 'Vera', 'Milton', 'Alma', 'Benjamin', 'Sylvia', 'Woodrow', 'Jane', 'Lewis', 'Ella', 'Martin', 'Lucy', 'Ray', 'Lillie', 'Marvin', 'Lena', 'Victor', 'Genevieve', 'Oscar', 'Jennie', 'Alvin', 'Mattie', 'Cecil', 'Leona', 'Stephen', 'Blanche', 'Gerald', 'Vivian', 'Jesse', 'Barbara', 'Vernon', 'Violet', 'Lee', 'Marguerite', 'Leon', 'Mae', 'Morris', 'Ellen', 'Edgar', 'Rita', 'Gordon', 'Charlotte', 'Sidney', 'Opal', 'Everett', 'Marian', 'Glenn', 'Carrie', 'Willard', 'Theresa', 'Claude', 'Velma', 'Maurice', 'Juanita', 'Harvey', 'Wilma', 'Wilbur', 'Beulah', 'Arnold', 'Hattie', 'Alexander', 'Emily', 'Max', 'Fannie', 'Irving', 'Sophie'];
const fetchUsers = abortable(({startsWith}) => {
const users = names.filter(name => name[0] == startsWith);
return new Promise(resolve => {
setTimeout(resolve.bind(null, users), 500)
const handleSuccess = ::console.log;
const handleError = error => {
if (error.code === 'PROMISE_ABORTED') {
throw error;
let promise;
['A', 'B', 'C', 'D', 'E'].forEach(letter => {
if (promise) {
promise = fetchUsers({startsWith: letter});
promise.then(handleSuccess, handleError);
import abortable from './abortable';
import ErrorWrapper from 'error-wrapper';
class TimeoutError extends ErrorWrapper {
get code() {
return 'TIMEOUT';
const timeout = (time, promiseMaker) => async (...args) => {
args.slice(); // workaround babel bug. see
const promise = abortable(promiseMaker)(...args);
const timer = setTimeout(::promise.abort, time);
try {
const result = await promise;
return result;
} catch (error) {
if (error.code === 'PROMISE_ABORTED') {
throw new TimeoutError('Timed Out', error);
throw error;
export default timeout;

This comment has been minimized.

Copy link
Owner Author

@spudly spudly commented Jun 30, 2016

TODO: make this into an npm package

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.