iOS的异步处理神器——Promises

创业故事 阅读(1458)
真人赌博游戏网站

你是否患有多任务依赖?你是否被嵌套的块回调搞糊涂了?

来吧,投入Promises的怀抱。

回调任务是正常现象。例如,如果您购买产品,则需要下订单,然后等待后台返回。

单个任务,通常只需要一个块,非常清楚;

以上面的顺序为例,将其传递给网络层以获取块,然后在购买完成后回调。

但是,当有多个任务时,逻辑开始分支。同样,在购买商品的情况下,订单完成后,需要使用SDK发起付款,然后根据付款结果提出一些提示:

任务1是一个订单。执行回调错误指针(或状态代码)后,它指示完成状态,并生成挂单信息。此时,生成分支,并且成功继续下一步,并执行错误块;

然后,执行任务2购买,执行异步支付,并根据支付结果生成分支。

当连续任务超过两个时,分支将导致代码逻辑非常混乱。

简单地绘制流程图进行分析,上述逻辑变得复杂的原因是因为块的每个级别需要处理块的下一级的失败,导致逻辑分支的数量增加。

事实上,所有故障的处理方式都类似:记录,提示用户,并将它们放在一起进行统一处理。

然后,任务一,任务二等连续执行,过程非常清楚。

Promises是一个用于协助实现此类设计的库。

实现的代码如下所示:

使用承诺

Promises库的介绍非常简单,可以使用CocoaPod,Podfile如下:

您也可以从GitHub手动下载它。

根据Promise设计模式的规范,每个Promise应该有三种状态:待定,履行,拒绝;

对应承诺是:

在实践中,我们使用的Promises库提供了很好的便利功能:

启动异步任务:

或者只使用do方法:

无论是异步方法还是do方法,它们的返回值是创建一个Promise对象,你可以在Promise对象之后挂起一个then方法,指示任务在Promise执行后继续:

上面的catch方法表示统一的错误处理。

承诺完成后,如果满足以下条件,则调用then方法:

1,直接调用履行;

2,在do方法中返回一个值(不能是错误);

3.在then方法中返回一个值;

调用reject方法或返回NSError对象将转到catch方法。

使用上面的do,catch方法组合来完成多个异步任务的依赖执行:

Promises还提供了许多其他功能,例如All和Any:

一切都是完成所有承诺的完成;

任何完成任何Promise完成;

承诺原则分析

Promises库设计简单,基于Promise设计模式和iOS的GCD。

整个图书馆由Promise.m/.h和他的Catagory组成。 Catagory是一个附加功能,它基于Promise.m/.h提供的方法进行扩展,因此专注于Promise.m/h。

Promise类的公共头文件只有几个方法:

重点是private.h提供的两种方法:

observeOnQueue方法是promise的实例方法。根据promise的当前状态,如果它是一个满足或被拒绝的状态,dispatch_group_async将执行相应的onFulfill和onReject回调;如果它处于挂起状态,将创建_observers数组,并将创建_observers数组。添加块回调。承诺完成后,根据状态选择onFulfill或onReject回调。

chainOnQueue方法也是promise的实例方法,它返回一个FBLPromise对象(状态为pending)。

该方法首先创建promise对象,然后创建解析器的回调,然后调用observeOnQueue方法。

在执行self(也是promise)之后,将根据fulfill和reject回调类型执行chainedFulfill和chainedReject;

最后,结果被抛出到解析器执行。解析器将根据返回值进行判断。如果它仍然是一个承诺,它将以递归方式执行。否则,将直接调用fulfill方法。

fulfill方法将确定值是否为NSError,如果是NSError则更改为reject,否则将状态更改为Fulfilled并通知观察者数组。

Promises中的Dispat_group_enter()和dispatch_group_leave()成对使用,但在和平时使用GCD时,此处不使用dispath_group_notify方法。

在Promises源代码的开头,有一个问题,为什么所有Promises操作都应放在同一个组中?

在找到FBLWaitForPromisesWithTimeout方法之前,有一个dispatch_group_wait方法(等待组中的所有块完成执行,或者在指定时间后回调)。

dispatch_group_wait方法类似于dispath_group_notify方法,只是它有一个额外的超时。如果调用dispatch_group_wait(DISPATCH_TIME_FOREVER),则它与dispath_group_notify方法相同。

还有许多其他功能,类似于Retry,Delay等,但在实践中,Promise使用了一些do,then,catch,async等来满足需求。

有许多库可以实现Promise设计模式。 Promise更适合性能和界面调用清晰度。

使用设计模式简化了逻辑并使代码更加健壮。

PromiseKit