Reputation: 6603
I'm just toying around with some ideas for my framework, lets say I extended the promise class like this
class cool_promise extends Promise {
cool_function() {
console.log("I am cool");
}
}
and had an async function like
async cool_function() {
return "functioning";
}
now by default cool_function just returns a regular Promise when executed synchronously but is it possible to make the async functions specific to my framework return my extended promise class instead?
Upvotes: 3
Views: 998
Reputation: 141829
The async
keyword will always cause a function to return a native Promise. To return a custom promise your function needs to be declared without async
and return the Promise directly.
You could write your async functions like normal but wrap them with a function that returns a CoolPromise instead before exposing them as part of your framework's interface:
class CoolPromise extends Promise {
coolFunction ( ) {
return 'I am cool';
}
static decorate ( func ) {
return function (...args) {
return CoolPromise.resolve( func.call( this, ...args ) );
};
}
}
// Some module with an async function in it
const module = function Module ( ) {
async function foo( ) {
return 'bar';
}
// Decorate functions before exposing them from your modules
return {
foo: CoolPromise.decorate( foo )
};
}( );
// Verify that module.foo( ) returns a CoolPromise
(async ( ) => {
console.log( await module.foo( ) );
console.log( module.foo( ).coolFunction( ) );
})();
Upvotes: 2
Reputation: 224862
No, you would have to convert it manually with cool_promise.resolve(cool_function())
. Without using a JavaScript preprocessor, async functions will always return a native Promise
.
An alternative sometimes is to extend the native Promise
prototype:
Object.defineProperty(Promise.prototype, 'cool_function', {
configurable: true,
writable: true,
value() {
console.log("I am cool");
},
});
Modifying globals always risks conflicting with other libraries/user code or later changes to the language, though. Sometimes it’s better to just have a standalone function. Maybe it’ll be possible to use that kind of function in a pipeline similar to the method call syntax someday – for example, there’s a proposal that would let you do this or something like it:
const cool_extension = (promise) => {
console.log("I am cool");
};
cool_function() |> cool_extension
// cool_function().cool_extension(), when extending prototype
And in the meantime, cool_extension(cool_function())
is not too bad and comfortably familiar.
Upvotes: 1