Some things that are "better" with this BetterPromise
implementation:
-
BetterPromise # then(..)
accepts aBetterPromise
(orPromise
) instance passed directly, instead of requiring a function to return it, so that the promise is linked into the chain.var p = BetterPromise.resolve(42); var q = Promise.resolve(10); p.then(console.log).then(q).then(console.log); // 42 // 10
-
BetterPromise # unthen(..)
/BetterPromise # uncatch(..)
/BetterPromise # unfinally(..)
allows you to unregister a fulfillment or rejection handler that you previously registered on a promise viathen(..)
orcatch(..)
, or unregister a resolution handler that you previously registered on a promise viafinally(..)
.NOTE: This seems to be the majority use-case for why many like/want "promise cancelation" -- IOW, often what you want is to just stop observing a promise's resolution, not actually forcibly cancel the operation is comes from.
var p = new BetterPromise(function(res){ setTimeout(function(){ res(42); },100); }); function f1(v) { console.log(`f1: ${v}`); } function f2(v) { console.log(`f2: ${v}`); } function f3() { console.log("finally!"); } p.then(f1); p.then(f2); p.finally(f3); p.unthen(f1); p.unfinally(f3); // later // f2: 42
-
BetterPromise # finally(..)
is included (assumed implemented since it's already stage-4). Registers a resolution handler which is called on either fulfillment or rejection, sorta like if you didthen( fn, fn )
(but not exactly).var p = BetterPromise.resolve(42); p .finally(function(){ console.log("resolved!"); }) .then(function(v){ console.log(`still: ${v}`); }); // resolved! // still: 42
-
BetterPromise # thenLog()
/BetterPromise # catchLog()
inserts a step in a promise chain that simply prints the value to the console (console.log
for fulfillment,console.error
for rejection) and passes the value or rejection along to the next step untouched.var p = BetterPromise.resolve(42); p .thenLog() .then(function(v){ console.log(`still: ${v}`); }); // 42 // still: 42
-
Instead of silently being swallowed, if a synchronous exception is thrown in a
BetterPromise
constructor after the promise has already been synchronously resolved (fulfillment or rejection), that exception overrides and causes the promise to be rejected with that exception.var p = new BetterPromise(function(res){ res(42); throw 10; }); p.then( function(v){ console.log(`then: ${v}`); }, function(e){ console.log(`oops: ${e}`); } ); // oops: 10
-
BetterPromise.try(..)
(static helper) is implemented (so not just draft). Runs a function (with no arguments) synchronously, returns a promise for its return value (or adopts its promise), catches any synchronous exception and turns it into a rejection.var p = BetterPromise.try(function(){ undefined(42); }); p.catch(console.log); // TypeError: undefined is not a function
-
BetterPromise.deferred(..)
(static helper) constructs an instance of the promise, but also extracts itsresolve(..)
andreject(..)
capabilities, and returns all 3 in an object (aka, a "deferred").var { pr, resolve, reject } = BetterPromise.deferred(); pr.then(console.log); resolve(42); // 42
-
BetterPromise.lift(..)
(static helper) lifts an error-first, callback-last style function to beBetterPromise
returning instead.var readFile = BetterPromise.lift(fs.readFile); readFile("/path/to/file.txt") .then(printContents);
-
BetterPromise.control(..)
(static helper) wraps a function so that when called, it first creates anAbortController
instance, passes in itssignal
as the first argument to the original function, and returns a controller object that has both apr
for the function's completion, as well as acancel(..)
to send the abort signal. Ostensibly, the original function can then observe/respond to that passed-in signal and do something appropriate with it, like canceling its own behavior, passing it tofetch(..)
to abort an Ajax call, etc.async function main(signal,url) { signal.addEventListener("abort", .. ); // .. var resp = await fetch(url, { signal }); // .. } var fn = BetterPromise.control(main); var { pr, cancel } = fn("http://some.url"); pr.then(..); // later cancel(); // sends cancelation signal into `fn(..)`
Great ideas, enjoyed the read.