规范
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
then
method.
PromiseKit 定义了如下接口
|
|
pipe
将传入的函数放入到待执行队列中。如果 Promise 已经完成,则立即执行传入的函数。
PromiseKit 提供了一下 then
方法的默认实现
|
|
其中 fulfill
的情况很有意思,摘录出来
|
|
其中它调用了 body
满足了立即执行的要求,检查 rv
和 rp
是符合以下规则
If
promise
and x refer to the same object, rejectpromise
with aTypeError
as 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
##参考资料