Legacy browser support: Issue with subclassing "Promise"
See original GitHub issueRelated to #51.
react-async is hard to use in legacy ES5 browsers due to the implementation of NeverSettle class. The problem is subclassing native Promise is not supported in well-known transpilers, and to achieve this we have to polyfill Reflect and use custom transpilers.
References:
- babel: https://github.com/babel/babel/issues/1120
- typescript: https://github.com/microsoft/TypeScript/issues/15397
Built-in classes such as Date, Array, DOM etc cannot be properly subclassed due to limitations in ES5 (for the transform-classes plugin). You can try to use babel-plugin-transform-builtin-extend based on Object.setPrototypeOf and Reflect.construct, but it also has some limitations. https://babeljs.io/docs/en/caveats/#classes
Let me show an example:
-
transpiled (ES5)
var NeverSettle = (function (_super) {
__extends(NeverSettle, _super);
function NeverSettle() {
var _this = _super.call(this, function () { }, function () { }) || this;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^ TypeError: undefined is not a promise
if (Object.setPrototypeOf) {
Object.setPrototypeOf(_this, NeverSettle.prototype);
}
return _this;
}
NeverSettle.prototype.finally = function () {
return this;
};
NeverSettle.prototype.catch = function () {
return this;
};
NeverSettle.prototype.then = function () {
return this;
};
return NeverSettle;
}(Promise));
- simple reproducible code about the error:
Promise.call(this, function () {}, function () {})
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^ TypeError: undefined is not a promise
at Promise (<anonymous>)
So I wish we can change the NeverSettle implementation rather than force us to set it up that complex setup. For example:
class NeverSettle {
constructor() {
const promise = new Promise(() => {}, () => {});
this.then = promise.then.bind(promise);
this.catch = promise.catch.bind(promise);
this.finally = promise.finally.bind(promise);
}
}
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:9 (9 by maintainers)

Top Related StackOverflow Question
Hey, thanks for reporting this! It’s a pretty big problem so we need to find a proper solution. However, the
new Promiseworkaround is not the right one. This was in fact the original implementation, but it was changed because it causes a memory leak, where callbacks chained on it will never be called and never garbage collected, because the promise itself never resolves. So instead, I’m looking to do something like this:Awesome. I’ll ship it early next week, as I’m out for the weekend.