@@ -20,6 +20,7 @@ func WithResolvers[T any]() (*Promise[T], func(T), func(error)) {
2020func WithResolversWithMgr [T any ](manager * PromiseMgr ) (* Promise [T ], func (T ), func (error )) {
2121 p := & Promise [T ]{
2222 manager : manager ,
23+ done : make (chan struct {}),
2324 }
2425
2526 p .state .Store (Pending )
@@ -40,6 +41,7 @@ func WithResolversWithMgr[T any](manager *PromiseMgr) (*Promise[T], func(T), fun
4041func NewWithMgr [T any ](manager * PromiseMgr , executor func (resolve func (T ), reject func (error ))) * Promise [T ] {
4142 p := & Promise [T ]{
4243 manager : manager ,
44+ done : make (chan struct {}),
4345 }
4446
4547 p .state .Store (Pending )
@@ -83,7 +85,6 @@ func NewWithMgr[T any](manager *PromiseMgr, executor func(resolve func(T), rejec
8385 return p
8486}
8587
86- // resolve fulfills the Promise
8788func (p * Promise [T ]) resolve (value T ) {
8889 if ! p .setState (Fulfilled ) {
8990 return
@@ -92,9 +93,6 @@ func (p *Promise[T]) resolve(value T) {
9293 p .setValue (value )
9394
9495 p .mu .Lock ()
95- if p .done == nil {
96- p .done = make (chan struct {})
97- }
9896 select {
9997 case <- p .done :
10098 p .mu .Unlock ()
@@ -120,7 +118,6 @@ func (p *Promise[T]) resolve(value T) {
120118 }
121119}
122120
123- // reject rejects the Promise
124121func (p * Promise [T ]) reject (err error ) {
125122 if ! p .setState (Rejected ) {
126123 return
@@ -130,9 +127,6 @@ func (p *Promise[T]) reject(err error) {
130127 p .setError (finalErr )
131128
132129 p .mu .Lock ()
133- if p .done == nil {
134- p .done = make (chan struct {})
135- }
136130 select {
137131 case <- p .done :
138132 p .mu .Unlock ()
@@ -167,7 +161,7 @@ func (p *Promise[T]) reject(err error) {
167161
168162func (p * Promise [T ]) Then (onFulfilled func (T ) any , onRejected func (error ) any ) * Promise [any ] {
169163 next := & Promise [any ]{
170- done : nil ,
164+ done : make ( chan struct {}) ,
171165 manager : p .manager ,
172166 }
173167
@@ -225,7 +219,7 @@ func (p *Promise[T]) Catch(onRejected func(error) any) *Promise[any] {
225219
226220func (p * Promise [T ]) Finally (onFinally func ()) * Promise [T ] {
227221 next := & Promise [T ]{
228- done : nil ,
222+ done : make ( chan struct {}) ,
229223 manager : p .manager ,
230224 }
231225
@@ -272,30 +266,62 @@ func (p *Promise[T]) Finally(onFinally func()) *Promise[T] {
272266}
273267
274268func (p * Promise [T ]) Await () (T , error ) {
275- p .mu .Lock ()
276- if p .done == nil {
277- p .done = make (chan struct {})
269+ state := p .getState ()
270+ if state == Fulfilled {
271+ if value , ok := p .getValue (); ok {
272+ return value , nil
273+ }
278274 }
275+ if state == Rejected {
276+ if err , ok := p .getError (); ok {
277+ var zero T
278+ return zero , err
279+ }
280+ }
281+
282+ p .mu .Lock ()
279283 done := p .done
280284 p .mu .Unlock ()
281285
282286 <- done
283287
284- if p .getState () == Fulfilled {
285- value , _ := p .getValue ()
286- return value , nil
288+ state = p .getState ()
289+ if state == Fulfilled {
290+ if value , ok := p .getValue (); ok {
291+ return value , nil
292+ }
293+ var zero T
294+ return zero , & PromiseError {
295+ Message : "Promise fulfilled but value not available" ,
296+ Type : RejectionError ,
297+ }
287298 }
299+
288300 var zero T
289- err , _ := p .getError ()
290- return zero , err
301+ if err , ok := p .getError (); ok {
302+ return zero , err
303+ }
304+ return zero , & PromiseError {
305+ Message : "Promise rejected but error not available" ,
306+ Type : RejectionError ,
307+ }
291308}
292309
293- // AwaitWithContext waits for Promise completion with context
294310func (p * Promise [T ]) AwaitWithContext (ctx context.Context ) (T , error ) {
295- p .mu .Lock ()
296- if p .done == nil {
297- p .done = make (chan struct {})
311+ state := p .getState ()
312+ if state == Fulfilled {
313+ if value , ok := p .getValue (); ok {
314+ return value , nil
315+ }
298316 }
317+ if state == Rejected {
318+ if err , ok := p .getError (); ok {
319+ var zero T
320+ return zero , err
321+ }
322+ }
323+
324+ p .mu .Lock ()
299325 done := p .done
300326 p .mu .Unlock ()
301327
@@ -306,36 +332,44 @@ func (p *Promise[T]) AwaitWithContext(ctx context.Context) (T, error) {
306332 case <- done :
307333 }
308334
309- if p .getState () == Fulfilled {
310- value , _ := p .getValue ()
311- return value , nil
335+ state = p .getState ()
336+ if state == Fulfilled {
337+ if value , ok := p .getValue (); ok {
338+ return value , nil
339+ }
340+ var zero T
341+ return zero , & PromiseError {
342+ Message : "Promise fulfilled but value not available" ,
343+ Type : RejectionError ,
344+ }
312345 }
346+
313347 var zero T
314- err , _ := p .getError ()
315- return zero , err
348+ if err , ok := p .getError (); ok {
349+ return zero , err
350+ }
351+ return zero , & PromiseError {
352+ Message : "Promise rejected but error not available" ,
353+ Type : RejectionError ,
354+ }
316355}
317356
318- // State gets the Promise state
319357func (p * Promise [T ]) State () State {
320358 return p .getState ()
321359}
322360
323- // IsPending checks if Promise is pending
324361func (p * Promise [T ]) IsPending () bool {
325362 return p .State () == Pending
326363}
327364
328- // IsFulfilled checks if Promise is fulfilled
329365func (p * Promise [T ]) IsFulfilled () bool {
330366 return p .State () == Fulfilled
331367}
332368
333- // IsRejected checks if Promise is rejected
334369func (p * Promise [T ]) IsRejected () bool {
335370 return p .State () == Rejected
336371}
337372
338- // safeCallback wraps callback with panic recovery
339373func safeCallback [T any ](callback func (T ) any , value T , next * Promise [any ]) {
340374 if next == nil {
341375 callback (value )
@@ -367,7 +401,6 @@ func safeCallback[T any](callback func(T) any, value T, next *Promise[any]) {
367401 next .resolve (result )
368402}
369403
370- // safeErrorCallback wraps error callback with panic recovery
371404func safeErrorCallback (callback func (error ) any , err error , next * Promise [any ]) {
372405 if next == nil {
373406 callback (err )
@@ -378,21 +411,19 @@ func safeErrorCallback(callback func(error) any, err error, next *Promise[any])
378411 if r := recover (); r != nil {
379412 var panicErr error
380413 if e , ok := r .(error ); ok {
381- // Wrap original error, preserve context
382414 panicErr = & PromiseError {
383415 Message : "panic in error callback" ,
384416 Cause : e ,
385417 Type : PanicError ,
386- OriginalError : err , // Preserve original error being processed
418+ OriginalError : err ,
387419 }
388420 } else {
389- // Non-error panic, wrap as error but preserve original value
390421 panicErr = & PromiseError {
391422 Message : fmt .Sprintf ("panic in error callback: %v" , r ),
392423 Cause : nil ,
393424 Type : PanicError ,
394425 Value : r ,
395- OriginalError : err , // Preserve original error being processed
426+ OriginalError : err ,
396427 }
397428 }
398429 next .reject (panicErr )
@@ -403,7 +434,6 @@ func safeErrorCallback(callback func(error) any, err error, next *Promise[any])
403434 next .resolve (result )
404435}
405436
406- // safeFinallyCallback wraps finally callback with panic recovery
407437func safeFinallyCallback [T any ](callback func (), next * Promise [T ], value T , err error ) {
408438 if next == nil {
409439 callback ()
@@ -414,28 +444,25 @@ func safeFinallyCallback[T any](callback func(), next *Promise[T], value T, err
414444 if r := recover (); r != nil {
415445 var panicErr error
416446 if e , ok := r .(error ); ok {
417- // Wrap original error, preserve context
418447 panicErr = & PromiseError {
419448 Message : "panic in finally callback" ,
420449 Cause : e ,
421450 Type : PanicError ,
422- OriginalError : err , // Preserve original error (if any)
451+ OriginalError : err ,
423452 }
424453 } else {
425- // Non-error panic, wrap as error but preserve original value
426454 panicErr = & PromiseError {
427455 Message : fmt .Sprintf ("panic in finally callback: %v" , r ),
428456 Cause : nil ,
429457 Type : PanicError ,
430458 Value : r ,
431- OriginalError : err , // Preserve original error (if any)
459+ OriginalError : err ,
432460 }
433461 }
434462 next .reject (panicErr )
435463 return
436464 }
437465
438- // Finally callback completed successfully, resolve with original value
439466 if err == nil {
440467 next .resolve (value )
441468 } else {
0 commit comments