angular Promises详解($q服务)

这是我在翻阅资料的时候,在国外的thinkster上找到的一篇关于关于angular中promise的一篇资料教程,写的非常好,收益良多,我现在翻译一下,供大家学习交流,如果大家想深入学习,欢迎到thinkster注册,并且付费。
下面是正文:
angular的promise是由$q提供和构件的,$q提供了一个通过注册一个promise项目来异步执行的方法。Promise作为ES6的一部分规范形成了原生javascript。angular的$q服务提供了一个新的接口,方便与以后移植到ES6。
code

<html>
<head>
           <tittle>Promise fun</tittle>
</head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.5/angular.min.js"></script> 
<script src="app.js"></script> 
<body ng-app="app">
 </body>
</html>
function getData($timeout, $q) {
  return function() {
    var defer = $q.defer()
    // simulated async function
    $timeout(function() {
    }, 2000)
    return defer.promise
  }
}
angular.module('app', [])
.factory('getData', getData)//把getData方法进入factory进行实例化,方便进去run方法进行配置
.run(function(getData) {//run方法用于快速配置,注入完成后启动(只能是实例化的服务或者参数可以配置)
  var promise = getData()
})

为了简单起见,我们使用angular的$timeout服务模拟异步函数,尤其是讲解AJAX使用angular的$HTTP服务,是最常用使用promise的地方

异步对象

延迟对象是一个简单的对象当为了解决这个promise对象暴露出一个promise对象,它是使用$q.defer()方法来构建,并且暴露出三个主要的方法,resolve() reject()和notify();这个相关联的promise对象能够通过promise对象属性来访问.

function getData(){
  return function(){
      var defer=$q.defer();
      $timeout(function(){
            defer.resolve("data received");
       },2000);
      return defer.promise;
  }
}

这里创建了一个promise对象,然后返回promise对象的属性,执行异步函数当函数完成后,我们解析这个延迟对象,这个resoleve()函数的参数会被传递到回调函数中。

Promise对象

现在我们获得了一个promise对象(defer.promise),让我们注册一个回调函数,当异步函数完成后执行。使用then()方法,附加一个回调函数,用来返回promise对象用来打印返回的string对象。

.run(function(getData){
    var promise=getData()
    .then(function(){
        console.log(string);
    })
})

拒绝一个promise对象

我们已经见过如何成功解析一个promise对象,但是当异步函数失败的时候会发生什么,相比于使用Resolve()方法,我们称reject()方法如果当失败的时候使用。
使用Math.random()来模拟失败然后返回这个promise对象,一半的机会。

function getData($timeout,$q){
    var defer=$q.defer();
    $timeout(function(){
         if(Math.round(Math.rondom())){
            defer.solve('data received!')
          }else{
            defer.reject('oh no an error! try again');  
           }
    },2000)
    return defer.promise;
}

then()方法的第二个参数是一个可选的发生错误时候的回调函数,当这个promise对象失败的时候调用。
给then()传入第二个作为执行发生错误时的回调函数。

.run(function(getData){
      var promise=getData()
      .then(function(string){
          console.log(string)
      },function(error){
          console.log(error);
      })
})

使用$q构造函数

使用$q服务本身能够快速变换一个基于异步函数的回调函数,形成一种快速解决方案。
重写这个模拟的异步函数用来返回一个promise对象使用$q函数。

function($timeout,$q){
    return function(){
        return $q(function(resolve,reject){
            $timeout(function(){
                if(Math.ronund(Math.random())){
                    resolve('data received!')
                 }else{
                    reject('oh no an error! try again')
                  }
             },2000)
        })
    }
}

这个方法完成了同样的事情,手动的创建了一个延迟对象,

finally()方法

promise对象只能成功执行函数或者失败回调函数能够被执行,但不是全部。但是当你需要确保这个方法执行忽略promise的结果。你可以通过使用finally()来注册这个方法,当对于一个已知状态的时候,很有用。
使用这个finally()方法来打印相应时间间隔,当异步函数完成时。

.run(function(getData) {
  var promise = getData()
    .then(function(string) {
      console.log(string)
    }, function(error) {
      console.error(error)
    })
    .finally(function() {
      console.log('Finished at:', new Date())
    })
})

现在你可以看到现在时间被打印出来,忽略了promise执行的状态。

promise链

最有魅力的promise特性就是能够使用使用链链接起来。它允许数据通过这个链流动,并且每一步进行操作和突变。
简单的示例:
现在修改我们的异步函数,用来传递一个0-9之间的随机数,到resolve()函数

function getData($timeout, $q) {
  return function() {
    // simulated async function
    return $q(function(resolve, reject) {
      $timeout(function() {
        resolve(Math.floor(Math.random() * 10))
      }, 2000)
    })
  }
}

当页面刷新,可以看到一个随机的interger数字在0-9之间跳动。
为了开始链式调用,我们必须修改这个回调函数返回一个value。
修改这个promise调用的回调函数用来返回一个随机数乘以2。

.run(function(getData) {
  var promise = getData()
    .then(function(num) {
      console.log(num)
      return num * 2
    })
})

现在我们能够链式调用另外一个回调函数对象使用then()方法,能够在第一个回调函数被执行后返回,这个值传入第二个回调函数被乘以2。

.run(function(getData) {
  var promise = getData()
    .then(function(num) {
      console.log(num)
      return num * 2
    })
    .then(function(num) {
      console.log(num) // = random number * 2
    })
})

这个例子虽然简单,但是说明了一个强大的概念,此外,不仅仅是从promise回调返回一个简单的值,能够返回新的promise对象。这个作用域链会暂停,知道返回这个回调成功。这样允许把多个异步回调串在一起。

下面是原文的连接,如果大家喜欢,可以到原网站学习。https://thinkster.io/a-better-way-to-learn-angularjs/promises
本文可以随意转载,但需注明出处。http://www.jianshu.com/p/df257dfbc8fe
这是我的github 文章分享的地方,欢迎交流。https://github.com/vista5004/article

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

推荐阅读更多精彩内容

  • 本文适用的读者 本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,...
    HZ充电大喵阅读 7,293评论 6 19
  • 00、前言Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区...
    夜幕小草阅读 2,127评论 0 12
  • Promise的含义:   Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和...
    呼呼哥阅读 2,161评论 0 16
  • Promiese 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,语法上说,Pr...
    雨飞飞雨阅读 3,348评论 0 19
  • 我与男友相交三年,口角、战争不断。因而,我常常怀疑我们的爱情究竟能够持续多久。 那天,我和男友又闹别扭,正在生闷气...
    丛铭阅读 337评论 6 9