Promise,RAC与高阶函数

1.什么是Promise

所谓 Promise,就是JS的一个对象,用来传递异步操作结果的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供了统一的 API,用来对异步调用需要的两种结果(成功与失败)进行处理。

Promise 使用示例:

1.使用new Promise(fn)创建并得到一个Promise对象,Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve方法和reject方法。
2.在 fn 中指定异步等处理
(1) 如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从"未完成" 变为"成功"(即从 pending 变为 resolved)。
(2) 如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从"未完成"变为"失败"(即从 pending 变为 rejected)。

3.通过promise的then方法,对不同状态的promise进行处理。

var promise = new Promise(function(resolve, reject) { 
  if (/* 异步操作成功 */){
    resolve(value);
  }  else {     
    reject(error);
  }
});

promise.then(function onFullfilled(value) {
  // success
}, function onRejected(error) {
  // failure
});

2.使用Promise与正常异步回调的区别

在callback的模型里边,我们假设需要执行一个异步队列,代码看起来可能像这样。

var adminIndex = function(params, callback) {
  storeAdmin.getApiTokens(function(err, tokens){    
    if ( err ) { 
      callback(err); 
      return;
     }
    storeAdmin.getApiServices(function(err, apiServices){
      if ( err ) {
        callback(err); 
        return; 
      }
      storeAdmin.getSocketioServices(function(err, socketioServices){
        if ( err ) { 
          callback(err); 
          return;
         }
        callback(0, {status : true,  data : {api_tokens : tokens,api_services : apiServices,socketio_services : socketioServices}});
      });
  });
});
};

这就是常说的回调金字塔,当异步的任务很多的时候,维护大量的callback将是一场灾难。而Promise则是把类似的异步处理对象和处理规则进行规范化, 并采用统一的接口来编写,除promise对象规定的方法(这里的 then 或 catch )以外的方法都是不可以使用的, 而不会像回调函数方式那样可以自己自由的定义回调函数的参数,从而必须严格遵守固定、统一的编程方式来编写代码。各个阶段抛出的错误都可以在一个catch下统一处理,同时promise的then方法会返回另一个promise对象,以便于形成promise管道,这种返回promise对象的方式能够支持开发人员把异步操作串联起来,从而避免了回调金子塔的状况,达到一个"线性编码、异步执行"的效果。

3.用.then 或 .catch 添加promise对象的处理函数

(1).Promise 状态:
Promise存在三个状态,分别是Fulfilled、 Rejected、 Pending。其创建后状态的初始化值为pending,当promise中的异步处理任务得到结果后,设置对应的Promise状态。而在使用Promise.resolve方法的时候,可以认为它的作用就是将异步操做返回的结果填充(Fulfilled)到promise对象并返回这个promise对象。


Promise状态

之后根据promise的不同状态,使用then方法对其进行相应的处理。

asyncFunction().then(function onFulfilled(value) {
      console.log(value);
}, function onRejected(error) {
      console.log(error);
});

(2).Promise catch:
Promise提供then方法加载回调函数,或者使用catch方法捕捉执行过程中抛出的错误。

aPromise.then(function taskA(value){
     // task A
}).then(function taskB(vaue){
     throw new Error(’taskB has a bug’);
}).catch(function onRejected(error){
     console.log(error);
});

以上数据处理流程相当于:

aPromise.then(function taskA(value){
     // task A
}).then(function taskB(vaue){
     throw new Error(’taskB has a bug’);
}).then(undefined, function onRejected(error){
     console.log(error);
});

使用promise中的 .then方法 、 .catch方法创建一个异步获取网络数据的流程
我们可以对过程中的匿名函数进行封装, 大概像这样: getURL(URL).then(parseJson(response)).then(checkResCode(json)).then(handleResponse(json)).catch(....)??梢苑⑾终舛未虢醮锏搅俗匀挥镅缘某潭?,十分优雅。
3.Promise chain:
每次调用promise的then方法后都会返回一个新的promise对象,通过这种特性我们可以创建对应的promise chain(类似RAC中的signalOperation, 每个signal的operation方法都返回一个signal)。

function taskA() {
     console.log("Task A");
}
function taskB() {
     console.log("Task B");
}
function onRejected(error) {
      console.log("Catch Error: A or B", error);
}
function finalTask() {
     console.log("Final Task");
}
var promise = Promise.resolve();
promise.then(taskA)
            .then(taskB)
            .catch(onRejected)
            .then(finalTask);

对应的流程图:


4.Promise与RAC的异同

以上的promise处理流程如果使用RAC来表示的话可以表示成下图代码:



RAC的CreateSignal 类似于创建一个promise;sendNext, sendError 可以看成resolve与reject操作;RAC中的try->try->catch 与 promise中的then->then-> catch相似。从相同的代码格式我们可以看出,RAC与Promise都是在初始化的时候,就规划好数据处理流程,使得代码更加直观与优雅,当然在两者比较举例的同时我们可以排除掉一些不影响宏观层面上不同点,比如:RAC信号需要被订阅,而Promise在创建好后即执行内部代码等。
除去以上的异同点,非常值得关注的就是RAC与Promise都采用了高阶函数的思想。何为高阶函数?高阶函数是至少满足以下两个条件其中之一的函数:1.接收一个或多个函数作为输入。2.输出一个函数。(同时FP下高阶函数都有一个共性:可以链式调用)。比如promise中的then, catch使用了函数参数, RAC的try, catch使用了block就是很好的例子。再比如swift中提供的filter, reduce 与map等。那么它们使用高阶函数有什么好处呢?能够将现有的代码由许多粒度非常小的功能函数来组合,如果将粒度缩到足够小的话,这些小粒度的功能函数能够达到极强的通用性,有通用性就可以对其进行下沉, 使其能够为其它??槭褂谩W詈?,原先的信号流或者数据流就会由大量的小粒度功能函数构成,从而把繁琐而又乏味的任务抽象出来,这将使代码显的直观与优雅。
修改后的RAC代码:

修改后的promise代码:

RAC与Promise还有一个相同的优点,纵向加载。在SDK写网络接口回调的时候,往往我们需要验证各种数据的正确性,condition1, condition2, condition3...每个验证条件都是一个if-else, 条件一多,if-else的多层嵌套让人眩晕,不仅不利于它人review,对于编码者而言,时间一久也会头大。同时多层的嵌套也非常容易漏掉抛往上层的错误通知。这种通过嵌套if-else的写法称之为横向发展,这样的代码很快就会乱成一团,无法管理。

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容

  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 11,025评论 26 95
  • Promiese 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,语法上说,Pr...
    雨飞飞雨阅读 3,355评论 0 19
  • 00、前言Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区...
    夜幕小草阅读 2,129评论 0 12
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 8,678评论 0 29
  • 4月2日晚8点天使班毕业典礼,每人3分钟??У淅裎揖褪巧弦拱嗍碧?,因为网络信号不好,听的断断续续,真是一个...
    韩溪流阅读 737评论 3 4