From 731be48b30065f4a95359af155f05e105fb411fb Mon Sep 17 00:00:00 2001 From: lee <876794356@qq.com> Date: Fri, 17 Nov 2023 19:24:55 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9promise=E5=86=85=E5=AD=98?= =?UTF-8?q?=E5=B8=83=E5=B1=80=EF=BC=8C=E6=8F=90=E9=AB=98=E4=BA=86=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E6=80=A7=EF=BC=8C=E5=87=8F=E5=B0=91=E4=BA=86=E5=86=85?= =?UTF-8?q?=E5=AD=98=E5=8D=A0=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- promise/promise.go | 69 +++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/promise/promise.go b/promise/promise.go index 6e413699..c0294f32 100644 --- a/promise/promise.go +++ b/promise/promise.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "sync" + "sync/atomic" "github.com/duke-git/lancet/v2/internal" ) @@ -16,14 +17,15 @@ import ( // ref : chebyrash/promise (https://github.com/chebyrash/promise) // see js promise: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise type Promise[T any] struct { + *p_[T] +} + +type p_[T any] struct { runnable func(resolve func(T), reject func(error)) result T err error - - pending bool - - mu *sync.Mutex - wg *sync.WaitGroup + wait sync.WaitGroup + pending atomic.Bool } // New create a new promise instance. @@ -32,12 +34,13 @@ func New[T any](runnable func(resolve func(T), reject func(error))) *Promise[T] panic("runnable function should not be nil") } - p := &Promise[T]{ + p := &Promise[T]{&p_[T]{ runnable: runnable, - pending: true, - mu: &sync.Mutex{}, - wg: &sync.WaitGroup{}, - } + wait: sync.WaitGroup{}, + pending: atomic.Bool{}, + }} + + p.pending.Store(true) defer p.run() @@ -45,11 +48,11 @@ func New[T any](runnable func(resolve func(T), reject func(error))) *Promise[T] } func (p *Promise[T]) run() { - p.wg.Add(1) + p.p_.wait.Add(1) go func() { defer func() { - if !p.pending { + if !p.pending.Load() { return } @@ -64,50 +67,42 @@ func (p *Promise[T]) run() { // Resolve returns a Promise that has been resolved with a given value. func Resolve[T any](resolution T) *Promise[T] { - return &Promise[T]{ + return &Promise[T]{&p_[T]{ result: resolution, - pending: false, - mu: &sync.Mutex{}, - wg: &sync.WaitGroup{}, - } + wait: sync.WaitGroup{}, + pending: atomic.Bool{}, + }} } func (p *Promise[T]) resolve(value T) { - p.mu.Lock() - defer p.mu.Unlock() - - if !p.pending { + if !p.pending.Load() { return } p.result = value - p.pending = false + p.pending.Store(false) - p.wg.Done() + p.wait.Done() } // Reject returns a Promise that has been rejected with a given error. func Reject[T any](err error) *Promise[T] { - return &Promise[T]{ + return &Promise[T]{&p_[T]{ err: err, - pending: false, - mu: &sync.Mutex{}, - wg: &sync.WaitGroup{}, - } + wait: sync.WaitGroup{}, + pending: atomic.Bool{}, + }} } func (p *Promise[T]) reject(err error) { - p.mu.Lock() - defer p.mu.Unlock() - - if !p.pending { + if !p.pending.Load() { return } p.err = err - p.pending = false + p.pending.Store(false) - p.wg.Done() + p.wait.Done() } // Then allows chain calls to other promise methods. @@ -149,18 +144,18 @@ func Catch[T any](promise *Promise[T], rejection func(err error) error) *Promise // Catch chain an existing promise with an intermediate reject function. func (p *Promise[T]) Catch(reject func(error) error) *Promise[T] { return New(func(resolve func(T), rej func(error)) { - resutl, err := p.Await() + result, err := p.Await() if err != nil { rej(reject(err)) return } - resolve(resutl) + resolve(result) }) } // Await blocks until the 'runable' to finish execution. func (p *Promise[T]) Await() (T, error) { - p.wg.Wait() + p.wait.Wait() return p.result, p.err } From 7d78d67488bce0807a839b86b618d65e36e47c06 Mon Sep 17 00:00:00 2001 From: lee <30332409+lee157953@users.noreply.github.com> Date: Sat, 18 Nov 2023 14:22:22 +0800 Subject: [PATCH 2/2] Update promise_test.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 单测失败修复 --- promise/promise_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/promise/promise_test.go b/promise/promise_test.go index 677e46cb..9c1d5cc4 100644 --- a/promise/promise_test.go +++ b/promise/promise_test.go @@ -16,7 +16,7 @@ func TestResolve(t *testing.T) { p := Resolve("abc") assert.Equal("abc", p.result) - assert.Equal(false, p.pending) + assert.Equal(false, p.pending.Load()) } func TestReject(t *testing.T) { @@ -28,7 +28,7 @@ func TestReject(t *testing.T) { p := Reject[string](err) assert.Equal("error", p.err.Error()) - assert.Equal(false, p.pending) + assert.Equal(false, p.pending.Load()) } func TestThen(t *testing.T) {