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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

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