promise版本的golang

2019-07-30 18:59:22 浏览数 (1)

之前我们分析了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是目前梳理的比较详细的

0 人点赞