Skip to content

Commit

Permalink
Fix Promise.race and upgrade dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorhakes committed Jun 13, 2019
1 parent acc989f commit 74d3029
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 21 deletions.
25 changes: 20 additions & 5 deletions dist/polyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ function finallyConstructor(callback) {
var constructor = this.constructor;
return this.then(
function(value) {
// @ts-ignore
return constructor.resolve(callback()).then(function() {
return value;
});
},
function(reason) {
// @ts-ignore
return constructor.resolve(callback()).then(function() {
// @ts-ignore
return constructor.reject(reason);
});
}
Expand All @@ -27,6 +30,10 @@ function finallyConstructor(callback) {
// other code modifying setTimeout (like sinon.useFakeTimers())
var setTimeoutFunc = setTimeout;

function isArray(x) {
return Boolean(x && x.length);
}

function noop() {}

// Polyfill for Function.prototype.bind
Expand Down Expand Up @@ -184,8 +191,10 @@ Promise.prototype['finally'] = finallyConstructor;

Promise.all = function(arr) {
return new Promise(function(resolve, reject) {
if (!arr || typeof arr.length === 'undefined')
throw new TypeError('Promise.all accepts an array');
if (!isArray(arr)) {
return reject(new TypeError('Promise.all accepts an array'));
}

var args = Array.prototype.slice.call(arr);
if (args.length === 0) return resolve([]);
var remaining = args.length;
Expand Down Expand Up @@ -236,18 +245,24 @@ Promise.reject = function(value) {
});
};

Promise.race = function(values) {
Promise.race = function(arr) {
return new Promise(function(resolve, reject) {
for (var i = 0, len = values.length; i < len; i++) {
values[i].then(resolve, reject);
if (!isArray(arr)) {
return reject(new TypeError('Promise.race accepts an array'));
}

for (var i = 0, len = arr.length; i < len; i++) {
Promise.resolve(arr[i]).then(resolve, reject);
}
});
};

// Use polyfill for setImmediate for performance gains
Promise._immediateFn =
// @ts-ignore
(typeof setImmediate === 'function' &&
function(fn) {
// @ts-ignore
setImmediate(fn);
}) ||
function(fn) {
Expand Down
2 changes: 1 addition & 1 deletion dist/polyfill.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,26 @@
},
"homepage": "https://github.com/taylorhakes/promise-polyfill",
"devDependencies": {
"browserify": "^16.2.3",
"cross-env": "^5.1.1",
"eslint": "^4.11.0",
"google-closure-compiler": "^20180610.0.1",
"husky": "^0.14.3",
"karma": "^0.13.19",
"karma-browserify": "^4.4.2",
"karma": "^4.1.0",
"karma-browserify": "^6.0.0",
"karma-chrome-launcher": "^0.2.2",
"karma-mocha": "^0.2.1",
"lint-staged": "^5.0.0",
"mocha": "^2.3.4",
"mocha": "^6.1.4",
"npm-run-all": "^4.1.2",
"prettier": "^1.8.2",
"promises-aplus-tests": "*",
"rimraf": "^2.6.2",
"rollup": "^0.52.0",
"rollup-plugin-uglify": "^2.0.1",
"sinon": "^1.17.2",
"typescript": "^2.9.2"
"typescript": "^3.5.1",
"watchify": "^3.11.1"
},
"keywords": [
"promise",
Expand Down
3 changes: 3 additions & 0 deletions src/finally.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ function finallyConstructor(callback) {
var constructor = this.constructor;
return this.then(
function(value) {
// @ts-ignore
return constructor.resolve(callback()).then(function() {
return value;
});
},
function(reason) {
// @ts-ignore
return constructor.resolve(callback()).then(function() {
// @ts-ignore
return constructor.reject(reason);
});
}
Expand Down
22 changes: 17 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import promiseFinally from './finally';
// other code modifying setTimeout (like sinon.useFakeTimers())
var setTimeoutFunc = setTimeout;

function isArray(x) {
return Boolean(x && x.length);
}

function noop() {}

// Polyfill for Function.prototype.bind
Expand Down Expand Up @@ -161,8 +165,10 @@ Promise.prototype['finally'] = promiseFinally;

Promise.all = function(arr) {
return new Promise(function(resolve, reject) {
if (!arr || typeof arr.length === 'undefined')
throw new TypeError('Promise.all accepts an array');
if (!isArray(arr)) {
return reject(new TypeError('Promise.all accepts an array'));
}

var args = Array.prototype.slice.call(arr);
if (args.length === 0) return resolve([]);
var remaining = args.length;
Expand Down Expand Up @@ -213,18 +219,24 @@ Promise.reject = function(value) {
});
};

Promise.race = function(values) {
Promise.race = function(arr) {
return new Promise(function(resolve, reject) {
for (var i = 0, len = values.length; i < len; i++) {
values[i].then(resolve, reject);
if (!isArray(arr)) {
return reject(new TypeError('Promise.race accepts an array'));
}

for (var i = 0, len = arr.length; i < len; i++) {
Promise.resolve(arr[i]).then(resolve, reject);
}
});
};

// Use polyfill for setImmediate for performance gains
Promise._immediateFn =
// @ts-ignore
(typeof setImmediate === 'function' &&
function(fn) {
// @ts-ignore
setImmediate(fn);
}) ||
function(fn) {
Expand Down
140 changes: 134 additions & 6 deletions test/promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,12 @@ describe('Promise', function() {
});

it('should be called on failure', function(done) {
Promise.reject(new Error()).finally(function() {
assert.equal(arguments.length, 0, 'No arguments to onFinally');
done();
});
Promise.reject(new Error())
.finally(function() {
assert.equal(arguments.length, 0, 'No arguments to onFinally');
done();
})
.catch();
});

it('should not affect the result', function(done) {
Expand Down Expand Up @@ -342,9 +344,9 @@ describe('Promise', function() {
);
});
it('throws on a number', function() {
return Promise.all().then(
return Promise.all(20).then(
function() {
assert.fail(20);
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
Expand All @@ -371,5 +373,131 @@ describe('Promise', function() {
}
);
});
it('throws on multiple promises', function() {
return Promise.all([Promise.resolve(), Promise.resolve()]).then(
function() {
assert.ok(true);
},
function() {
assert.fail();
}
);
});
});
describe('Promise.race', function() {
it('throws on implicit undefined', function() {
return Promise.race().then(
function() {
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
}
);
});
it('throws on explicit undefined', function() {
return Promise.race(undefined).then(
function() {
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
}
);
});
it('throws on null', function() {
return Promise.race(null).then(
function() {
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
}
);
});
it('throws on 0', function() {
return Promise.race(0).then(
function() {
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
}
);
});
it('throws on false', function() {
return Promise.race(false).then(
function() {
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
}
);
});
it('throws on a number', function() {
return Promise.race(20).then(
function() {
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
}
);
});
it('throws on a boolean', function() {
return Promise.race(true).then(
function() {
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
}
);
});
it('throws on an object', function() {
return Promise.race({ test: 'object' }).then(
function() {
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
}
);
});
it('throws on multiple promises', function() {
return Promise.race(Promise.resolve(), Promise.resolve()).then(
function() {
assert.fail();
},
function(error) {
assert.ok(error instanceof Error);
}
);
});
it('works on basic values', function() {
return Promise.race([1, 2, 3]).then(
function(val) {
assert.ok(val == 1);
},
function() {
assert.fail();
}
);
});
it('works on success promise', function() {
var doneProm = Promise.resolve(10);
var pendingProm1 = new Promise(function() {});
var pendingProm2 = new Promise(function() {});

return Promise.race([pendingProm1, doneProm, pendingProm2]).then(
function(val) {
assert.ok(val == 10);
},
function() {
assert.fail();
}
);
});
});
});

0 comments on commit 74d3029

Please sign in to comment.