angular Promises詳解($q服務(wù))

這是我在翻閱資料的時(shí)候,在國(guó)外的thinkster上找到的一篇關(guān)于關(guān)于angular中promise的一篇資料教程,寫(xiě)的非常好,收益良多,我現(xiàn)在翻譯一下,供大家學(xué)習(xí)交流,如果大家想深入學(xué)習(xí),歡迎到thinkster注冊(cè),并且付費(fèi)。
下面是正文:
angular的promise是由$q提供和構(gòu)件的,$q提供了一個(gè)通過(guò)注冊(cè)一個(gè)promise項(xiàng)目來(lái)異步執(zhí)行的方法。Promise作為ES6的一部分規(guī)范形成了原生javascript。angular的$q服務(wù)提供了一個(gè)新的接口,方便與以后移植到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方法進(jìn)入factory進(jìn)行實(shí)例化,方便進(jìn)去run方法進(jìn)行配置
.run(function(getData) {//run方法用于快速配置,注入完成后啟動(dòng)(只能是實(shí)例化的服務(wù)或者參數(shù)可以配置)
  var promise = getData()
})

為了簡(jiǎn)單起見(jiàn),我們使用angular的$timeout服務(wù)模擬異步函數(shù),尤其是講解AJAX使用angular的$HTTP服務(wù),是最常用使用promise的地方

異步對(duì)象

延遲對(duì)象是一個(gè)簡(jiǎn)單的對(duì)象當(dāng)為了解決這個(gè)promise對(duì)象暴露出一個(gè)promise對(duì)象,它是使用$q.defer()方法來(lái)構(gòu)建,并且暴露出三個(gè)主要的方法,resolve() reject()和notify();這個(gè)相關(guān)聯(lián)的promise對(duì)象能夠通過(guò)promise對(duì)象屬性來(lái)訪問(wèn).

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

這里創(chuàng)建了一個(gè)promise對(duì)象,然后返回promise對(duì)象的屬性,執(zhí)行異步函數(shù)當(dāng)函數(shù)完成后,我們解析這個(gè)延遲對(duì)象,這個(gè)resoleve()函數(shù)的參數(shù)會(huì)被傳遞到回調(diào)函數(shù)中。

Promise對(duì)象

現(xiàn)在我們獲得了一個(gè)promise對(duì)象(defer.promise),讓我們注冊(cè)一個(gè)回調(diào)函數(shù),當(dāng)異步函數(shù)完成后執(zhí)行。使用then()方法,附加一個(gè)回調(diào)函數(shù),用來(lái)返回promise對(duì)象用來(lái)打印返回的string對(duì)象。

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

拒絕一個(gè)promise對(duì)象

我們已經(jīng)見(jiàn)過(guò)如何成功解析一個(gè)promise對(duì)象,但是當(dāng)異步函數(shù)失敗的時(shí)候會(huì)發(fā)生什么,相比于使用Resolve()方法,我們稱reject()方法如果當(dāng)失敗的時(shí)候使用。
使用Math.random()來(lái)模擬失敗然后返回這個(gè)promise對(duì)象,一半的機(jī)會(huì)。

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()方法的第二個(gè)參數(shù)是一個(gè)可選的發(fā)生錯(cuò)誤時(shí)候的回調(diào)函數(shù),當(dāng)這個(gè)promise對(duì)象失敗的時(shí)候調(diào)用。
給then()傳入第二個(gè)作為執(zhí)行發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。

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

使用$q構(gòu)造函數(shù)

使用$q服務(wù)本身能夠快速變換一個(gè)基于異步函數(shù)的回調(diào)函數(shù),形成一種快速解決方案。
重寫(xiě)這個(gè)模擬的異步函數(shù)用來(lái)返回一個(gè)promise對(duì)象使用$q函數(shù)。

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)
        })
    }
}

這個(gè)方法完成了同樣的事情,手動(dòng)的創(chuàng)建了一個(gè)延遲對(duì)象,

finally()方法

promise對(duì)象只能成功執(zhí)行函數(shù)或者失敗回調(diào)函數(shù)能夠被執(zhí)行,但不是全部。但是當(dāng)你需要確保這個(gè)方法執(zhí)行忽略promise的結(jié)果。你可以通過(guò)使用finally()來(lái)注冊(cè)這個(gè)方法,當(dāng)對(duì)于一個(gè)已知狀態(tài)的時(shí)候,很有用。
使用這個(gè)finally()方法來(lái)打印相應(yīng)時(shí)間間隔,當(dāng)異步函數(shù)完成時(shí)。

.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())
    })
})

現(xiàn)在你可以看到現(xiàn)在時(shí)間被打印出來(lái),忽略了promise執(zhí)行的狀態(tài)。

promise鏈

最有魅力的promise特性就是能夠使用使用鏈鏈接起來(lái)。它允許數(shù)據(jù)通過(guò)這個(gè)鏈流動(dòng),并且每一步進(jìn)行操作和突變。
簡(jiǎn)單的示例:
現(xiàn)在修改我們的異步函數(shù),用來(lái)傳遞一個(gè)0-9之間的隨機(jī)數(shù),到resolve()函數(shù)

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

當(dāng)頁(yè)面刷新,可以看到一個(gè)隨機(jī)的interger數(shù)字在0-9之間跳動(dòng)。
為了開(kāi)始鏈?zhǔn)秸{(diào)用,我們必須修改這個(gè)回調(diào)函數(shù)返回一個(gè)value。
修改這個(gè)promise調(diào)用的回調(diào)函數(shù)用來(lái)返回一個(gè)隨機(jī)數(shù)乘以2。

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

現(xiàn)在我們能夠鏈?zhǔn)秸{(diào)用另外一個(gè)回調(diào)函數(shù)對(duì)象使用then()方法,能夠在第一個(gè)回調(diào)函數(shù)被執(zhí)行后返回,這個(gè)值傳入第二個(gè)回調(diào)函數(shù)被乘以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
    })
})

這個(gè)例子雖然簡(jiǎn)單,但是說(shuō)明了一個(gè)強(qiáng)大的概念,此外,不僅僅是從promise回調(diào)返回一個(gè)簡(jiǎn)單的值,能夠返回新的promise對(duì)象。這個(gè)作用域鏈會(huì)暫停,知道返回這個(gè)回調(diào)成功。這樣允許把多個(gè)異步回調(diào)串在一起。

下面是原文的連接,如果大家喜歡,可以到原網(wǎng)站學(xué)習(xí)。https://thinkster.io/a-better-way-to-learn-angularjs/promises
本文可以隨意轉(zhuǎn)載,但需注明出處。http://www.itdecent.cn/p/df257dfbc8fe
這是我的github 文章分享的地方,歡迎交流。https://github.com/vista5004/article

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文適用的讀者 本文寫(xiě)給有一定Promise使用經(jīng)驗(yàn)的人,如果你還沒(méi)有使用過(guò)Promise,這篇文章可能不適合你,...
    HZ充電大喵閱讀 7,448評(píng)論 6 19
  • 00、前言Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。它由社區(qū)...
    夜幕小草閱讀 2,219評(píng)論 0 12
  • Promise的含義: ??Promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和...
    呼呼哥閱讀 2,264評(píng)論 0 16
  • Promiese 簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果,語(yǔ)法上說(shuō),Pr...
    雨飛飛雨閱讀 3,484評(píng)論 0 19
  • 我與男友相交三年,口角、戰(zhàn)爭(zhēng)不斷。因而,我常常懷疑我們的愛(ài)情究竟能夠持續(xù)多久。 那天,我和男友又鬧別扭,正在生悶氣...
    叢銘閱讀 398評(píng)論 6 9

友情鏈接更多精彩內(nèi)容