之前我们分析了swift版本的PromiseKit,最近也在琢磨能否移植到咱大golang上来,找了好久也没有相对应的粒子。于是经过一次失败的尝试之后这周末花了一天重新梳理了一下,好在不负有心人,虽然丑了点但是好坏算是跑起来啦
众所周知go推荐组合不推荐继承,但是这个promise还真是适合继承,不适合组合……唉,折腾人啊。
对于promise我想大家都有所了解,node c 均有成熟的粒子典型的方式就是链式响应,一条链到底:fetch().then(…).then(…)可谓是一爽到底啊
好了,说了这么多我们看看基于继承的promise吧
先睹为快,看一下我们怎么玩的
代码语言:javascript复制
sKPromise.Firstly(func() sKPromise.Thenable {
return sKPromise.Value("NNNNNN")
}).Then(func(value interface{}) sKPromise.Thenable {
fmt.Println("Then=>", value)
return sKPromise.Value(123233)
}).GetValue(func(v interface{}) {
sKPromise.Value(v)
}).Done(func(Value interface{}) {
fmt.Println("Done=>", Value)
}
粒子十分的简单,我们只是先实现了其中的一部分功能,先说一下我们的Firstly吧。其实对于这个完全可以不要,因为它之时起到一个承接的作用,数据完全没有转化只是为了作为一个看起来更加明显的其实而已。
然后就是我们的Then啦,它的作用就是进行一个数据传递的作用,目的就是起到一个承接的作用,一般来说不做数据的转化
最后是我们的Done,意思很明确就是整个数据链条传递结束。一般来说数据就是起源于Firstly结束于Done
说了这么多我们看看咱们都是如何实现的,在此之前我们看一下内存中的关系
通过截图我们可以明显看到几个数据类型Promise These Thenabel的关系
代码语言:javascript复制
type Thenable interface {
pipe(to func(result Result))
Get() Result
}
type Thense struct {
Thenable
}
type Promise struct {
Thense
box Box
}
然后是内部通过pipe来完成数据调传递
代码语言:javascript复制
func (promise Promise) pipe(to func(result Result)) {
sealant := promise.box.inspect()
if v, ok := sealant.resolved.(Result); ok {
to(v)
} else {
promise.box.inspectBlock(func(sealant Sealant) {
if v, ok := sealant.resolved.(Result); ok {
to(v)
} else {
sealant.pending.append(func(handler Handler) {
//error or value
if e, ok := handler.(error); ok {
to(Result{rejected: e})
} else {
to(Result{fulfilled: handler})
}
})
}
})
}
}
结合一下我们看看Then的实现
代码语言:javascript复制func (then Promise) Then(body func(value interface{}) Thenable) *Promise {
rp := EmptyPromise()
then.pipe(func(result Result) {
if result.rejected != nil {
rp.box.seal(Result{rejected: result.rejected})
} else {
rv := body(result.fulfilled)
if rv != rp {
rv.pipe(func(result Result) {
rp.box.seal(result)
})
} else {
panic("returnSlef:")
}
}
})
return &rp
}
Then的目的思路很明确,就是解包数据封装为Promise传递个下边
然后我们看Firstly
代码语言:javascript复制func Firstly(body func() Thenable) Promise {
rp := EmptyPromise()
b := body()
b.pipe(func(result Result) {
rp.box.seal(result)
})
return rp
}
通过firstyl的源码我们很容易看出来,内部没有数据类型的转换,就是起到一个开篇的告诉你咱们的Promise从这里开始啦。
好了基本的就这么多,等后续吧其余的基本功能梳理完成给大家整体的梳理一下思路。当然啦有兴趣的话可以去看看基于swift版本的那个介绍,swift版本的Promise是目前梳理的比较详细的