Skip to content

Commit

Permalink
fix&&add test
Browse files Browse the repository at this point in the history
  • Loading branch information
holy-func committed May 20, 2022
1 parent 2400fca commit 5e029e8
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 53 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,19 @@ Promise settled后一定会执行的函数 返回一个新的 *async.GOPromise
```
##### AllSettled()
```
和将*async.Plain传入async.Settled() 相同
和将*async.Plain传入async.Allsettled() 相同
```
##### All()
```
和将*async.Plain传入async.All() 相同
```
##### Any()
```
和将*async.Plain传入async.Any() 相同
```
##### Race()
```
和将*async.Plain传入async.Race() 相同
```

***
Expand Down
122 changes: 74 additions & 48 deletions async.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ import (
func (p *Plain) AllSettled() *GoPromise {
return AllSettled(p)
}
func (p *Plain) All() *GoPromise {
return All(p)
}
func (p *Plain) Race() *GoPromise {
return Race(p)
}
func (p *Plain) Any() *GoPromise {
return Any(p)
}
func (s *Settled) String() string {
return fmt.Sprintf("{ Status: %s, Value: %s }", s.Status, s.Value)
}
Expand All @@ -31,58 +40,64 @@ func (p *Plain) toPromise() *Tasks {
}
func (p *GoPromise) callback() {
if p.prototype != nil {
defer func() {
p.prototype = nil
}()
if p.prototype.then != nil {
v := p.prototype.then
if p.resolved() {
go func() {
prototype := p.prototype
p.prototype = p.prototype.next
if prototype.then != nil {
v := prototype.then
if p.resolved() {
go v.execPromise(func(resolve, reject Handler) {
if v.success != nil {
resolve(v.success(p.ret))
} else {
resolve(p.ret)
}
})
} else if p.rejected() {
go v.execPromise(func(resolve, reject Handler) {
if v.fail != nil {
p.err = false
resolve(v.fail(p.ret))
} else {
reject(p.ret)
}
})
} else {
clearTask()
}
} else if prototype.catch != nil {
v := prototype.catch
if v.handler != nil {
p.err = false
}
go v.execPromise(func(resolve, reject Handler) {
if v.success != nil {
resolve(v.success(p.ret))
if p.rejected() {
if v.handler != nil {
resolve(v.handler(p.ret))
} else {
reject(p.ret)
}
} else {
resolve(p.ret)
}
})
} else if p.rejected() {
} else if prototype.finally != nil {
v := prototype.finally
go v.execPromise(func(resolve, reject Handler) {
if v.fail != nil {
p.err = false
resolve(v.fail(p.ret))
} else {
reject(p.ret)
}
v.handler()
resolve(p.ret)
})
} else {
clearTask()
}
} else if p.prototype.catch != nil {
v := p.prototype.catch
if v.handler != nil {
p.err = false
}
go v.execPromise(func(resolve, reject Handler) {
if p.rejected() {
if v.handler != nil {
resolve(v.handler(p.ret))
} else {
reject(p.ret)
}
} else {
resolve(p.ret)
}
})
} else if p.prototype.finally != nil {
v := p.prototype.finally
go v.execPromise(func(resolve, reject Handler) {
v.handler()
resolve(p.ret)
})
}
p.callback()
}()
}
}
func (p *GoPromise) endTask() {
close(p.async)
p.callback()
clearTask()
p.callback()
}
func (l *lock) waitTask() {
if l.settled() {
Expand Down Expand Up @@ -113,15 +128,15 @@ func (p *GoPromise) resolve(v interface{}) {
} else {
p.state = Resolved
p.ret = ret
p.once.Do(p.endTask)
}
p.endTask()
}
}
func (p *GoPromise) reject(v interface{}) {
if !p.settled() {
p.ret = v
p.state = Rejected
p.endTask()
p.once.Do(p.endTask)
}
}
func (l *lock) Await() (ret interface{}, err interface{}) {
Expand Down Expand Up @@ -169,7 +184,6 @@ func (l *lock) String() string {
}
}


func (p *GoPromise) handleCallback() {
if p.settled() {
p.callback()
Expand All @@ -178,21 +192,33 @@ func (p *GoPromise) handleCallback() {
func (p *GoPromise) Then(success, fail CallBack) *GoPromise {
promise := gPromise()
collectTask()
p.prototype = &prototype{&then{success, fail, promise}, nil, nil}
go p.handleCallback()
if p.prototype == nil {
p.prototype = &prototype{&then{success, fail, promise}, nil, nil, nil}
} else {
p.prototype.next = &prototype{&then{success, fail, promise}, nil, nil, nil}
}
p.handleCallback()
return promise
}
func (p *GoPromise) Catch(handler CallBack) *GoPromise {
promise := gPromise()
collectTask()
p.prototype = &prototype{nil, &catch{handler, promise}, nil}
go p.handleCallback()
if p.prototype == nil {
p.prototype = &prototype{nil, &catch{handler, promise}, nil, nil}
} else {
p.prototype.next = &prototype{nil, &catch{handler, promise}, nil, nil}
}
p.handleCallback()
return promise
}
func (p *GoPromise) Finally(handler finallyHandler) *GoPromise {
promise := gPromise()
collectTask()
p.prototype = &prototype{nil, nil, &finally{handler, promise}}
go p.handleCallback()
if p.prototype == nil {
p.prototype = &prototype{nil, nil, &finally{handler, promise}, nil}
} else {
p.prototype.next = &prototype{nil, nil, &finally{handler, promise}, nil}
}
p.handleCallback()
return promise
}
87 changes: 87 additions & 0 deletions async_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package async

import (
"fmt"
"testing"
"time"
)

type thenAble struct {
name string
age int
}

func (t *thenAble) setThen(resolved bool, val int) promiseTask {
return func(resolve, reject Handler) {
if resolved {
resolve(val)
} else {
reject(val)
}
}
}
func asset(test bool) {
if !test {
panic("error")
}
}
func setTasks() *Plain {
return &Plain{1, 2,
Promise(func(resolve, reject Handler) {
resolve(3)
}),
Promise(func(resolve, reject Handler) {
reject(4)
}),
&thenAble{"hloy", 19},
}
}
func TestAll(t *testing.T) {
PROD()
promise := Do(func(params ...interface{}) interface{} {
asset(params[0].(int) == 1)
return 1 + params[0].(int)
}, 1).Then(func(ret interface{}) interface{} {
fmt.Println(ret,1)
asset(ret.(int) == 2)
return Resolve(ret)
}, nil).Then(func(ret interface{}) interface{} {
asset(ret.(int) == 2)
return Reject(ret)
}, nil).Then(nil, func(ret interface{}) interface{} {
asset(ret.(int) == 2)
return Reject(ret)
}).Catch(func(ret interface{}) interface{} {
asset(ret.(int) == 2)
return Promise((&thenAble{"holy-func", 19}).setThen(true, 2))
}).Finally(func() {
All(setTasks()).UnsafeAwait()
AllSettled(setTasks()).UnsafeAwait()
Any(setTasks()).UnsafeAwait()
Race(setTasks()).UnsafeAwait()
setTasks().All()
setTasks().AllSettled()
setTasks().Any()
setTasks().Race()
})
promise.Then(func(i interface{}) interface{} {
time.Sleep(time.Second*2)
fmt.Println(i, 3)
return 2
}, nil)
promise.Then(func(i interface{}) interface{} {
fmt.Println(i, 2)
return 3
}, nil)
fmt.Println(promise)
Wait()
fmt.Println(promise)
}
// Promise { <pending> }
// 2 1
// 2 2
// 2 3
// Promise { 2 }
// PASS
// coverage: 85.1% of statements
// ok github.com/holy-func/async 2.597s
4 changes: 2 additions & 2 deletions export.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ func Resolve(v interface{}) *GoPromise {
} else if promise, ok := isPromise(v); ok {
return promise
} else {
return &GoPromise{&lock{make(chan int), v, Resolved, false}, nil}
return &GoPromise{&lock{make(chan int), v, Resolved, false, nil}, nil}
}
}
func Reject(v interface{}) *GoPromise {
return &GoPromise{&lock{make(chan int), v, Rejected, false}, nil}
return &GoPromise{&lock{make(chan int), v, Rejected, false, nil}, nil}
}
func Do(task AsyncTask, params ...interface{}) *GoPromise {
return Promise(func(resolve, reject Handler) {
Expand Down
1 change: 0 additions & 1 deletion implement.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ func all(promises *Tasks) *GoPromise {
var newPromise *GoPromise
newPromise = Promise(func(resolve, reject Handler) {
for i, promise := range *promises {
wg.Add(1)
go func(i int, promise *GoPromise) {
ret, err := promise.UnsafeAwait()
if newPromise.settled() {
Expand Down
2 changes: 1 addition & 1 deletion tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func clearTask() {
wg.Done()
}
func gPromise() *GoPromise {
return &GoPromise{&lock{make(chan int), nil, Pending, false}, nil}
return &GoPromise{&lock{make(chan int), nil, Pending, false, &sync.Once{}}, nil}
}
func isPromise(v interface{}) (*GoPromise, bool) {
obj, ok := v.(*GoPromise)
Expand Down
2 changes: 2 additions & 0 deletions type.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type lock struct {
ret interface{}
state State
err bool
once *sync.Once
}
type State string
type Handler func(interface{})
Expand Down Expand Up @@ -47,6 +48,7 @@ type prototype struct {
*then
*catch
*finally
next *prototype
}

type GoPromise struct {
Expand Down

0 comments on commit 5e029e8

Please sign in to comment.