规范
PromiseKit - Swift 实现
Box and Result
Promise 最终的结果一定反映出两个状态,所以 PromisKit 定义了以下的 Result 枚举
|
|
Result 类型一定要把它看作最终的结果。
Promise 自身还有两个状态,pending(等待执行) 以及 resolved(执行完毕)
虽然在 PromiseKit 中有一个基类 Box 作为非正式协议使用
|
|
Box 中装了一个内部的类型 Sealant
|
|
Handlers 包装的是一些内部使用的函数,内部逻辑基本上是将当 then 中返回的 Promise 的状态传递到 then 返回的 Promise 中,见规范 2.3
Resolver
Resolver 是作为提供给 Promise 包装函数使用,用于触发 Promise 的工具,它基本提供的方法如下
|
|
fulfill 当包装函数执行成功时调用
reject 当保障函数执行失败时调用
Thenable
“thenable” is an object or function that defines a
thenmethod.
PromiseKit 定义了如下接口
|
|
pipe 将传入的函数放入到待执行队列中。如果 Promise 已经完成,则立即执行传入的函数。
PromiseKit 提供了一下 then 方法的默认实现
|
|
其中 fulfill 的情况很有意思,摘录出来
|
|
其中它调用了 body 满足了立即执行的要求,检查 rv 和 rp 是符合以下规则
If
promiseand x refer to the same object, rejectpromisewith aTypeErroras the reason.
rv.pipe(to: rp.box.seal) 则巧妙的实现了 2.3.2.1
If x is pending, promise must remain pending until x is fulfilled or rejected
Promise
一下是 PromiseKit 实现的简单版本
|
|
核心的 pip 函数完成 Handler 的接驳工作,逻辑就是检查 box 中的内容是否是 pending 是则将接驳函数放入队列中;否则就立即执行,把结果给出去。
总览
综合看 PromiseKit 的类名很有意思,但是它提供了一个很好的比喻。
每一个 Promise 都有一个 Box 来存储当前的状态以及被注册的 Handler。比如几个 Promise 用链式调用 then 方法可以得到如下的结果。pipe() 函数的公用就是连接两个 Promise 的 box, 同时 pipe() 也是一个开关,当 Box 没有打开的时候是不通的;当 Box seal() 的时候,Box 把其内容放出,下一个 box 中.
graph TD B1[Box1] -."P1.then()".-> B2[Box2] B1 --"P1.pip()"--> Body(body) Body -."body()".-> B3[Box3] B3 --"P1.pip(to)"--> B2
上图展示了一个 Promise 调用一次 then 产生的几个 Promise的关系,实线表示 Box 的数据流向,虚线表示 Promise 产生的关系。
Box 释放出来的数据进入 body(),它产生了一个新的 Promise ,然后用关键的一句
|
|
让 P3 来控制 P2 Box2 的释放,并将得到的数据传递给 Box2 ,让 Box2 seal 出去。
总结
看完感觉有很多可以学习的地方。
enum的使用,完成了状态和值的绑定。Box和pipe的抽象很让人很容易理解extension protocol的使用,给protocol一个默认的实现,让拓展protocol更加方便,提供更便捷的protocol
##参考资料