-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR adds a polyfill for `Promise.try`.
- Loading branch information
Showing
4 changed files
with
198 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
aliases = [ "es2025" ] | ||
dependencies = [ | ||
"_ESAbstract.Call", | ||
"_ESAbstract.CreateMethodProperty", | ||
"_ESAbstract.NewPromiseCapability", | ||
"_ESAbstract.NormalCompletion", | ||
"_ESAbstract.ThrowCompletion", | ||
"_ESAbstract.Type", | ||
"Function.prototype.name", | ||
"Promise", | ||
] | ||
license = "MIT" | ||
spec = "https://tc39.es/ecma262/#sec-promise.try" | ||
docs = "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/try" | ||
|
||
[browsers] | ||
android = "*" | ||
bb = "*" | ||
chrome = "<128" | ||
edge = "*" | ||
edge_mob = "*" | ||
firefox = "<132" | ||
firefox_mob = "*" | ||
ie = "*" | ||
ie_mob = "*" | ||
opera = "<114" | ||
op_mob = "*" | ||
op_mini = "*" | ||
safari = "<18.2" | ||
ios_saf = "<18.2" | ||
samsung_mob = "*" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"Promise" in self && "try" in self.Promise; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* global Call, CreateMethodProperty, NewPromiseCapability, NormalCompletion, Promise, ThrowCompletion, Type */ | ||
// 27.2.4.8 Promise.try ( callback, ...args ) | ||
CreateMethodProperty(Promise, "try", function Try(callback /* , ...args */) { | ||
var args = | ||
arguments.length > 1 ? Array.prototype.slice.call(arguments, 1) : []; | ||
// 1. Let C be the this value. | ||
var C = this; | ||
// 2. If C is not an Object, throw a TypeError exception. | ||
if (Type(C) !== "object") { | ||
throw new TypeError("`this` value must be an object"); | ||
} | ||
// 3. Let promiseCapability be ? NewPromiseCapability(C). | ||
var promiseCapability = NewPromiseCapability(C); | ||
// 4. Let status be Completion(Call(callback, undefined, args)). | ||
var status; | ||
try { | ||
status = NormalCompletion(Call(callback, undefined, args)); | ||
} catch (error) { | ||
status = ThrowCompletion(error); | ||
} | ||
// 5. If status is an abrupt completion, then | ||
if (status["[[Type]]"] === "throw") { | ||
// a. Perform ? Call(promiseCapability.[[Reject]], undefined, « status.[[Value]] »). | ||
Call(promiseCapability["[[Reject]]"], undefined, [status["[[Value]]"]]); | ||
} | ||
// 6. Else, | ||
else { | ||
// a. Perform ? Call(promiseCapability.[[Resolve]], undefined, « status.[[Value]] »). | ||
Call(promiseCapability["[[Resolve]]"], undefined, [status["[[Value]]"]]); | ||
} | ||
// 7. Return promiseCapability.[[Promise]]. | ||
return promiseCapability["[[Promise]]"]; | ||
}); | ||
|
||
(function () { | ||
var supportsDefiningFunctionName = (function () { | ||
var fn = function () {}; | ||
try { | ||
Object.defineProperty(fn, "name", { | ||
value: "test" | ||
}); | ||
return true; | ||
} catch (ignore) { | ||
return false; | ||
} | ||
})(); | ||
|
||
if (supportsDefiningFunctionName) { | ||
Object.defineProperty(Promise.try, "name", { | ||
value: "try", | ||
writable: false, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
} | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* global Promise */ | ||
var supportsDefiningFunctionName = (function () { | ||
var fn = function () {}; | ||
try { | ||
Object.defineProperty(fn, "name", { | ||
value: "test" | ||
}); | ||
return true; | ||
} catch (ignore) { | ||
return false; | ||
} | ||
})(); | ||
|
||
it("is a function", function () { | ||
proclaim.isFunction(Promise.try); | ||
}); | ||
|
||
it("has correct arity", function () { | ||
proclaim.arity(Promise.try, 1); | ||
}); | ||
|
||
it("has correct name", function () { | ||
if (supportsDefiningFunctionName) { | ||
proclaim.hasName(Promise.try, "try"); | ||
} else { | ||
proclaim.hasName(Promise.try, "Try"); | ||
} | ||
}); | ||
|
||
it("is not enumerable", function () { | ||
proclaim.isNotEnumerable(Promise, "try"); | ||
}); | ||
|
||
describe("try", function () { | ||
it("returns a Promise that resolves for a callback function that returns a value", function () { | ||
var promise = Promise.try(function () { | ||
return "ok"; | ||
}); | ||
return promise.then(function (value) { | ||
proclaim.equal(value, "ok"); | ||
}); | ||
}); | ||
|
||
it("returns a Promise that rejects for a callback function that throws synchronously", function () { | ||
var promise = Promise.try(function () { | ||
throw "not ok"; | ||
}); | ||
return promise.then( | ||
function () { | ||
proclaim.fail("promise did not reject"); | ||
}, | ||
function (error) { | ||
proclaim.equal(error, "not ok"); | ||
} | ||
); | ||
}); | ||
|
||
it("returns a Promise that resolves for a callback function that returns a Promise that resolves", function () { | ||
var promise = Promise.try(function () { | ||
return Promise.resolve("ok"); | ||
}); | ||
return promise.then(function (value) { | ||
proclaim.equal(value, "ok"); | ||
}); | ||
}); | ||
|
||
it("returns a Promise that rejects for a callback function that returns a Promise that rejects", function () { | ||
var promise = Promise.try(function () { | ||
return Promise.reject("not ok"); | ||
}); | ||
return promise.then( | ||
function () { | ||
proclaim.fail("promise did not reject"); | ||
}, | ||
function (error) { | ||
proclaim.equal(error, "not ok"); | ||
} | ||
); | ||
}); | ||
|
||
it("calls the callback function with variadic arguments", function () { | ||
var promise = Promise.try( | ||
function (a, b) { | ||
return a + b; | ||
}, | ||
1, | ||
2 | ||
); | ||
return promise.then(function (value) { | ||
proclaim.equal(value, 3); | ||
}); | ||
}); | ||
|
||
it("throws a TypeError for non-constructor `this`", function () { | ||
proclaim.throws(function () { | ||
Promise.try.call({}); | ||
}, TypeError); | ||
}); | ||
|
||
it("supports `this` as a Promise subclass", function () { | ||
function _Promise(executor) { | ||
return new Promise(executor); | ||
} | ||
_Promise.prototype = Promise.prototype; | ||
|
||
var _promise = Promise.try.call(_Promise, function () {}); | ||
|
||
proclaim.ok(_promise instanceof _Promise); | ||
}); | ||
}); |