TypeScript based Promise/A+ compliant, awaitable promise class for Node.js
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
4
down vote
favorite
This is yet another Node.js Promise implementation, but this is written in TypeScript, and it strives for type safety and clarity. The full project is located here. Feel free to download it and test it out.
Please give your comments regarding any missing bits or errors, as well as any potential improvements (I'm only 5 days into Node/TypeScript/JavaScript).
function isPromiseLike<T>(x: any): x is PromiseLike<T>
return x != null && (<PromiseLike<T>>x).then != undefined;
function isPromiseX<T>(x: PromiseLike<T>): x is PromiseX<T>
return x != null && (<PromiseX<T>>x).type == PromiseX.symbolPromiseX;
enum State Pending, Fulfilled, Rejected
export class PromiseX<T = any> implements PromiseLike<T>
static symbolPromiseX: symbol = Symbol('PromiseX');
readonly type: symbol = PromiseX.symbolPromiseX;
private _state: State = State.Pending;
private _result: T;
private _reason: any;
private _continuations: [(x: T) => void, (e: any) => void] = ;
constructor(executor?: (resolve: (value?: T
node.js promise async-await typescript
add a comment |Â
up vote
4
down vote
favorite
This is yet another Node.js Promise implementation, but this is written in TypeScript, and it strives for type safety and clarity. The full project is located here. Feel free to download it and test it out.
Please give your comments regarding any missing bits or errors, as well as any potential improvements (I'm only 5 days into Node/TypeScript/JavaScript).
function isPromiseLike<T>(x: any): x is PromiseLike<T>
return x != null && (<PromiseLike<T>>x).then != undefined;
function isPromiseX<T>(x: PromiseLike<T>): x is PromiseX<T>
return x != null && (<PromiseX<T>>x).type == PromiseX.symbolPromiseX;
enum State Pending, Fulfilled, Rejected
export class PromiseX<T = any> implements PromiseLike<T>
static symbolPromiseX: symbol = Symbol('PromiseX');
readonly type: symbol = PromiseX.symbolPromiseX;
private _state: State = State.Pending;
private _result: T;
private _reason: any;
private _continuations: [(x: T) => void, (e: any) => void] = ;
constructor(executor?: (resolve: (value?: T
node.js promise async-await typescript
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
This is yet another Node.js Promise implementation, but this is written in TypeScript, and it strives for type safety and clarity. The full project is located here. Feel free to download it and test it out.
Please give your comments regarding any missing bits or errors, as well as any potential improvements (I'm only 5 days into Node/TypeScript/JavaScript).
function isPromiseLike<T>(x: any): x is PromiseLike<T>
return x != null && (<PromiseLike<T>>x).then != undefined;
function isPromiseX<T>(x: PromiseLike<T>): x is PromiseX<T>
return x != null && (<PromiseX<T>>x).type == PromiseX.symbolPromiseX;
enum State Pending, Fulfilled, Rejected
export class PromiseX<T = any> implements PromiseLike<T>
static symbolPromiseX: symbol = Symbol('PromiseX');
readonly type: symbol = PromiseX.symbolPromiseX;
private _state: State = State.Pending;
private _result: T;
private _reason: any;
private _continuations: [(x: T) => void, (e: any) => void] = ;
constructor(executor?: (resolve: (value?: T
node.js promise async-await typescript
This is yet another Node.js Promise implementation, but this is written in TypeScript, and it strives for type safety and clarity. The full project is located here. Feel free to download it and test it out.
Please give your comments regarding any missing bits or errors, as well as any potential improvements (I'm only 5 days into Node/TypeScript/JavaScript).
function isPromiseLike<T>(x: any): x is PromiseLike<T>
return x != null && (<PromiseLike<T>>x).then != undefined;
function isPromiseX<T>(x: PromiseLike<T>): x is PromiseX<T>
return x != null && (<PromiseX<T>>x).type == PromiseX.symbolPromiseX;
enum State Pending, Fulfilled, Rejected
export class PromiseX<T = any> implements PromiseLike<T>
static symbolPromiseX: symbol = Symbol('PromiseX');
readonly type: symbol = PromiseX.symbolPromiseX;
private _state: State = State.Pending;
private _result: T;
private _reason: any;
private _continuations: [(x: T) => void, (e: any) => void] = ;
constructor(executor?: (resolve: (value?: T
node.js promise async-await typescript
edited Jan 14 at 2:56
Jamalâ¦
30.1k11114225
30.1k11114225
asked Jan 14 at 2:51
Dejavu
1233
1233
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
First, a few notes from your GitHub project
The most important compiler option to turn on is
strict
. This protects you from many common errors and makes it much nicer when defining optional type parameters. After turning on strict mode, the| undefined
part can be dropped from parameters. (Personally, I'd like to also dropnull
to enforce the use of a consistent. See null is bad)Consider using a proper testing framework, tests should ideally be quick and easy to read to see exactly what the code should be doing. The current testing code prints out a bunch of numbers without telling me for sure if everything is working or not. I will recommend Ava (potentially along with
ava-ts
) for the convenience of how it is designed to be used with promises. You could also just use this project to test your implementation.
Now on to your code :) In no particular order...
Instead of defining a
isPromiseX
function, you might consider implementing theSymbol.hasInstance
method and just usingif (x instanceof PromiseX)
With the default promise implementation in Chrome at least, if the passed
executor
function throws an error, the promise will be rejected. (Does not seem to be covered by the spec). It might be worth duplicating this behavior.setResult
andsetError
should not be public. They are only used internally.I prefer early returns to nested code, in every case where you wrap a function's body with
if (this._state == State.Pending)
, I would prefer to check if the state is not pending and return.The code is not fully spec compliant. See point 2.3.1 is not fulfilled.
Instead of defining
setResult
andsetError
as prototype methods, since you pass them into functions it may be worth defining them with arrow functions as demonstrated here.private setResult = (result?: T | PromiseLike<T>): void => {
Good work on the implementation overall!
Thanks for your comments, Gerrit0! IâÂÂll explore the Symbol system and it seems using instanceof is a more intuitive way of doing type guards. This implementation is meant for node.js and server side, so chrome compatibility is not my greatest concern, but your point is taken as a good reference. setResult/setError are public for convenience testing things, so I donâÂÂt have to hook them to another âÂÂproducerâÂÂ. I like early return too. Honestly, I didnâÂÂt really read through the resolution spec, the implementation was largely based on âÂÂcommon senseâÂÂ, IâÂÂll read through the spec though.
â Dejavu
Jan 16 at 6:27
Regarding the arrow function, IâÂÂm still not too clear regarding the difference between the way I defined them vs the arrow function approach: for the arrow function approach, can I pass âÂÂthis.setResultâ around? Because I knew when I defined it my way, the âÂÂthisâ context was lost, thats why I had to use a closure to wrap it. Thanks again for your suggestions!
â Dejavu
Jan 16 at 6:32
Oh, regarding the first point (having extraundefined
andnull
union types), the reason is that I'm actually implementing the TypeScript definedPromiseLike<T>
interface, whosethen
method is defined exactly like that. I was not too sure if I should just omit theundefined
andnull
type, so I just included them in, and didn't bother too much.
â Dejavu
Jan 16 at 6:37
Arrow functions: see the playground
â Gerrit0
Jan 16 at 20:37
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
First, a few notes from your GitHub project
The most important compiler option to turn on is
strict
. This protects you from many common errors and makes it much nicer when defining optional type parameters. After turning on strict mode, the| undefined
part can be dropped from parameters. (Personally, I'd like to also dropnull
to enforce the use of a consistent. See null is bad)Consider using a proper testing framework, tests should ideally be quick and easy to read to see exactly what the code should be doing. The current testing code prints out a bunch of numbers without telling me for sure if everything is working or not. I will recommend Ava (potentially along with
ava-ts
) for the convenience of how it is designed to be used with promises. You could also just use this project to test your implementation.
Now on to your code :) In no particular order...
Instead of defining a
isPromiseX
function, you might consider implementing theSymbol.hasInstance
method and just usingif (x instanceof PromiseX)
With the default promise implementation in Chrome at least, if the passed
executor
function throws an error, the promise will be rejected. (Does not seem to be covered by the spec). It might be worth duplicating this behavior.setResult
andsetError
should not be public. They are only used internally.I prefer early returns to nested code, in every case where you wrap a function's body with
if (this._state == State.Pending)
, I would prefer to check if the state is not pending and return.The code is not fully spec compliant. See point 2.3.1 is not fulfilled.
Instead of defining
setResult
andsetError
as prototype methods, since you pass them into functions it may be worth defining them with arrow functions as demonstrated here.private setResult = (result?: T | PromiseLike<T>): void => {
Good work on the implementation overall!
Thanks for your comments, Gerrit0! IâÂÂll explore the Symbol system and it seems using instanceof is a more intuitive way of doing type guards. This implementation is meant for node.js and server side, so chrome compatibility is not my greatest concern, but your point is taken as a good reference. setResult/setError are public for convenience testing things, so I donâÂÂt have to hook them to another âÂÂproducerâÂÂ. I like early return too. Honestly, I didnâÂÂt really read through the resolution spec, the implementation was largely based on âÂÂcommon senseâÂÂ, IâÂÂll read through the spec though.
â Dejavu
Jan 16 at 6:27
Regarding the arrow function, IâÂÂm still not too clear regarding the difference between the way I defined them vs the arrow function approach: for the arrow function approach, can I pass âÂÂthis.setResultâ around? Because I knew when I defined it my way, the âÂÂthisâ context was lost, thats why I had to use a closure to wrap it. Thanks again for your suggestions!
â Dejavu
Jan 16 at 6:32
Oh, regarding the first point (having extraundefined
andnull
union types), the reason is that I'm actually implementing the TypeScript definedPromiseLike<T>
interface, whosethen
method is defined exactly like that. I was not too sure if I should just omit theundefined
andnull
type, so I just included them in, and didn't bother too much.
â Dejavu
Jan 16 at 6:37
Arrow functions: see the playground
â Gerrit0
Jan 16 at 20:37
add a comment |Â
up vote
3
down vote
accepted
First, a few notes from your GitHub project
The most important compiler option to turn on is
strict
. This protects you from many common errors and makes it much nicer when defining optional type parameters. After turning on strict mode, the| undefined
part can be dropped from parameters. (Personally, I'd like to also dropnull
to enforce the use of a consistent. See null is bad)Consider using a proper testing framework, tests should ideally be quick and easy to read to see exactly what the code should be doing. The current testing code prints out a bunch of numbers without telling me for sure if everything is working or not. I will recommend Ava (potentially along with
ava-ts
) for the convenience of how it is designed to be used with promises. You could also just use this project to test your implementation.
Now on to your code :) In no particular order...
Instead of defining a
isPromiseX
function, you might consider implementing theSymbol.hasInstance
method and just usingif (x instanceof PromiseX)
With the default promise implementation in Chrome at least, if the passed
executor
function throws an error, the promise will be rejected. (Does not seem to be covered by the spec). It might be worth duplicating this behavior.setResult
andsetError
should not be public. They are only used internally.I prefer early returns to nested code, in every case where you wrap a function's body with
if (this._state == State.Pending)
, I would prefer to check if the state is not pending and return.The code is not fully spec compliant. See point 2.3.1 is not fulfilled.
Instead of defining
setResult
andsetError
as prototype methods, since you pass them into functions it may be worth defining them with arrow functions as demonstrated here.private setResult = (result?: T | PromiseLike<T>): void => {
Good work on the implementation overall!
Thanks for your comments, Gerrit0! IâÂÂll explore the Symbol system and it seems using instanceof is a more intuitive way of doing type guards. This implementation is meant for node.js and server side, so chrome compatibility is not my greatest concern, but your point is taken as a good reference. setResult/setError are public for convenience testing things, so I donâÂÂt have to hook them to another âÂÂproducerâÂÂ. I like early return too. Honestly, I didnâÂÂt really read through the resolution spec, the implementation was largely based on âÂÂcommon senseâÂÂ, IâÂÂll read through the spec though.
â Dejavu
Jan 16 at 6:27
Regarding the arrow function, IâÂÂm still not too clear regarding the difference between the way I defined them vs the arrow function approach: for the arrow function approach, can I pass âÂÂthis.setResultâ around? Because I knew when I defined it my way, the âÂÂthisâ context was lost, thats why I had to use a closure to wrap it. Thanks again for your suggestions!
â Dejavu
Jan 16 at 6:32
Oh, regarding the first point (having extraundefined
andnull
union types), the reason is that I'm actually implementing the TypeScript definedPromiseLike<T>
interface, whosethen
method is defined exactly like that. I was not too sure if I should just omit theundefined
andnull
type, so I just included them in, and didn't bother too much.
â Dejavu
Jan 16 at 6:37
Arrow functions: see the playground
â Gerrit0
Jan 16 at 20:37
add a comment |Â
up vote
3
down vote
accepted
up vote
3
down vote
accepted
First, a few notes from your GitHub project
The most important compiler option to turn on is
strict
. This protects you from many common errors and makes it much nicer when defining optional type parameters. After turning on strict mode, the| undefined
part can be dropped from parameters. (Personally, I'd like to also dropnull
to enforce the use of a consistent. See null is bad)Consider using a proper testing framework, tests should ideally be quick and easy to read to see exactly what the code should be doing. The current testing code prints out a bunch of numbers without telling me for sure if everything is working or not. I will recommend Ava (potentially along with
ava-ts
) for the convenience of how it is designed to be used with promises. You could also just use this project to test your implementation.
Now on to your code :) In no particular order...
Instead of defining a
isPromiseX
function, you might consider implementing theSymbol.hasInstance
method and just usingif (x instanceof PromiseX)
With the default promise implementation in Chrome at least, if the passed
executor
function throws an error, the promise will be rejected. (Does not seem to be covered by the spec). It might be worth duplicating this behavior.setResult
andsetError
should not be public. They are only used internally.I prefer early returns to nested code, in every case where you wrap a function's body with
if (this._state == State.Pending)
, I would prefer to check if the state is not pending and return.The code is not fully spec compliant. See point 2.3.1 is not fulfilled.
Instead of defining
setResult
andsetError
as prototype methods, since you pass them into functions it may be worth defining them with arrow functions as demonstrated here.private setResult = (result?: T | PromiseLike<T>): void => {
Good work on the implementation overall!
First, a few notes from your GitHub project
The most important compiler option to turn on is
strict
. This protects you from many common errors and makes it much nicer when defining optional type parameters. After turning on strict mode, the| undefined
part can be dropped from parameters. (Personally, I'd like to also dropnull
to enforce the use of a consistent. See null is bad)Consider using a proper testing framework, tests should ideally be quick and easy to read to see exactly what the code should be doing. The current testing code prints out a bunch of numbers without telling me for sure if everything is working or not. I will recommend Ava (potentially along with
ava-ts
) for the convenience of how it is designed to be used with promises. You could also just use this project to test your implementation.
Now on to your code :) In no particular order...
Instead of defining a
isPromiseX
function, you might consider implementing theSymbol.hasInstance
method and just usingif (x instanceof PromiseX)
With the default promise implementation in Chrome at least, if the passed
executor
function throws an error, the promise will be rejected. (Does not seem to be covered by the spec). It might be worth duplicating this behavior.setResult
andsetError
should not be public. They are only used internally.I prefer early returns to nested code, in every case where you wrap a function's body with
if (this._state == State.Pending)
, I would prefer to check if the state is not pending and return.The code is not fully spec compliant. See point 2.3.1 is not fulfilled.
Instead of defining
setResult
andsetError
as prototype methods, since you pass them into functions it may be worth defining them with arrow functions as demonstrated here.private setResult = (result?: T | PromiseLike<T>): void => {
Good work on the implementation overall!
answered Jan 15 at 23:21
Gerrit0
2,6701518
2,6701518
Thanks for your comments, Gerrit0! IâÂÂll explore the Symbol system and it seems using instanceof is a more intuitive way of doing type guards. This implementation is meant for node.js and server side, so chrome compatibility is not my greatest concern, but your point is taken as a good reference. setResult/setError are public for convenience testing things, so I donâÂÂt have to hook them to another âÂÂproducerâÂÂ. I like early return too. Honestly, I didnâÂÂt really read through the resolution spec, the implementation was largely based on âÂÂcommon senseâÂÂ, IâÂÂll read through the spec though.
â Dejavu
Jan 16 at 6:27
Regarding the arrow function, IâÂÂm still not too clear regarding the difference between the way I defined them vs the arrow function approach: for the arrow function approach, can I pass âÂÂthis.setResultâ around? Because I knew when I defined it my way, the âÂÂthisâ context was lost, thats why I had to use a closure to wrap it. Thanks again for your suggestions!
â Dejavu
Jan 16 at 6:32
Oh, regarding the first point (having extraundefined
andnull
union types), the reason is that I'm actually implementing the TypeScript definedPromiseLike<T>
interface, whosethen
method is defined exactly like that. I was not too sure if I should just omit theundefined
andnull
type, so I just included them in, and didn't bother too much.
â Dejavu
Jan 16 at 6:37
Arrow functions: see the playground
â Gerrit0
Jan 16 at 20:37
add a comment |Â
Thanks for your comments, Gerrit0! IâÂÂll explore the Symbol system and it seems using instanceof is a more intuitive way of doing type guards. This implementation is meant for node.js and server side, so chrome compatibility is not my greatest concern, but your point is taken as a good reference. setResult/setError are public for convenience testing things, so I donâÂÂt have to hook them to another âÂÂproducerâÂÂ. I like early return too. Honestly, I didnâÂÂt really read through the resolution spec, the implementation was largely based on âÂÂcommon senseâÂÂ, IâÂÂll read through the spec though.
â Dejavu
Jan 16 at 6:27
Regarding the arrow function, IâÂÂm still not too clear regarding the difference between the way I defined them vs the arrow function approach: for the arrow function approach, can I pass âÂÂthis.setResultâ around? Because I knew when I defined it my way, the âÂÂthisâ context was lost, thats why I had to use a closure to wrap it. Thanks again for your suggestions!
â Dejavu
Jan 16 at 6:32
Oh, regarding the first point (having extraundefined
andnull
union types), the reason is that I'm actually implementing the TypeScript definedPromiseLike<T>
interface, whosethen
method is defined exactly like that. I was not too sure if I should just omit theundefined
andnull
type, so I just included them in, and didn't bother too much.
â Dejavu
Jan 16 at 6:37
Arrow functions: see the playground
â Gerrit0
Jan 16 at 20:37
Thanks for your comments, Gerrit0! IâÂÂll explore the Symbol system and it seems using instanceof is a more intuitive way of doing type guards. This implementation is meant for node.js and server side, so chrome compatibility is not my greatest concern, but your point is taken as a good reference. setResult/setError are public for convenience testing things, so I donâÂÂt have to hook them to another âÂÂproducerâÂÂ. I like early return too. Honestly, I didnâÂÂt really read through the resolution spec, the implementation was largely based on âÂÂcommon senseâÂÂ, IâÂÂll read through the spec though.
â Dejavu
Jan 16 at 6:27
Thanks for your comments, Gerrit0! IâÂÂll explore the Symbol system and it seems using instanceof is a more intuitive way of doing type guards. This implementation is meant for node.js and server side, so chrome compatibility is not my greatest concern, but your point is taken as a good reference. setResult/setError are public for convenience testing things, so I donâÂÂt have to hook them to another âÂÂproducerâÂÂ. I like early return too. Honestly, I didnâÂÂt really read through the resolution spec, the implementation was largely based on âÂÂcommon senseâÂÂ, IâÂÂll read through the spec though.
â Dejavu
Jan 16 at 6:27
Regarding the arrow function, IâÂÂm still not too clear regarding the difference between the way I defined them vs the arrow function approach: for the arrow function approach, can I pass âÂÂthis.setResultâ around? Because I knew when I defined it my way, the âÂÂthisâ context was lost, thats why I had to use a closure to wrap it. Thanks again for your suggestions!
â Dejavu
Jan 16 at 6:32
Regarding the arrow function, IâÂÂm still not too clear regarding the difference between the way I defined them vs the arrow function approach: for the arrow function approach, can I pass âÂÂthis.setResultâ around? Because I knew when I defined it my way, the âÂÂthisâ context was lost, thats why I had to use a closure to wrap it. Thanks again for your suggestions!
â Dejavu
Jan 16 at 6:32
Oh, regarding the first point (having extra
undefined
and null
union types), the reason is that I'm actually implementing the TypeScript defined PromiseLike<T>
interface, whose then
method is defined exactly like that. I was not too sure if I should just omit the undefined
and null
type, so I just included them in, and didn't bother too much.â Dejavu
Jan 16 at 6:37
Oh, regarding the first point (having extra
undefined
and null
union types), the reason is that I'm actually implementing the TypeScript defined PromiseLike<T>
interface, whose then
method is defined exactly like that. I was not too sure if I should just omit the undefined
and null
type, so I just included them in, and didn't bother too much.â Dejavu
Jan 16 at 6:37
Arrow functions: see the playground
â Gerrit0
Jan 16 at 20:37
Arrow functions: see the playground
â Gerrit0
Jan 16 at 20:37
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185078%2ftypescript-based-promise-a-compliant-awaitable-promise-class-for-node-js%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password