angularjs promise詳解

来源:https://www.cnblogs.com/chaixiaozhi/archive/2018/03/14/8570588.html
-Advertisement-
Play Games

一、什麼是Promise Promise是對象,代表了一個函數最終可能的返回值或拋出的異常,就是用來非同步處理值的。 Promise是一個構造函數,自己身上有all、reject、resolve這幾個非同步方式處理值的方法,原型上有then、catch等同樣很眼熟的方法。 二、為什麼使用Promise ...


一、什麼是Promise

Promise是對象,代表了一個函數最終可能的返回值或拋出的異常,就是用來非同步處理值的。

Promise是一個構造函數,自己身上有all、reject、resolve這幾個非同步方式處理值的方法,原型上有then、catch等同樣很眼熟的方法。

 

二、為什麼使用Promise

有了Promise對象,就可以把非同步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。此外,Promise對象提供了統一的介面,使得控制非同步操作更加容易。

Promise對象有以下2個特點: 

1.對象的狀態不受外界影響。

Promise對象代表一個非同步操作,有三種狀態:Pending(進行中)Resolved(已完成)Rejected(已失敗)。只有非同步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。

2.一旦狀態改變,就不會再變,任何時候都可以得到這個結果。

Promise對象的狀態改變,只有兩種可能:從Pending變為Resolved;從Pending變為Rejected。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果。

 

三、如何創建一個Promise

先貼一段代碼:

define([
    'angularModule'
],function (app) {
    app.register.service('httpRequestService', ['$http', '$q', function ($http, $q) {
        return{
            request: function (params) {
                var deferred = $q.defer();
                $http({
                    method : params.method,
                    url : params.url
                }).success(
                    function (data) {
                        deferred.resolve(data);
                    }
                ).error(
                    function(data){
                        deferred.reject(data);
                    }
                );
                return deferred.promise;
            }
        }
    }])
});

 

 講一下$q服務

q服務是AngularJS中自己封裝實現的一種Promise實現。

要創建一個deferred對象,可以調用defer()方法:

var deferred = $q.defer();  //deffered上面暴露了三個方法,以及一個可以用於處理promise的promise屬性。  //promise屬性裡面又包含了then、catch、finally三個方法

在Promise中,定義了三種狀態:等待狀態,完成狀態,拒絕狀態。

 

deffered API

1.deffered 對象的方法

1.resolve(value):在聲明resolve()處,表明promise對象由pending狀態轉變為resolve。
2.reject(reason):在聲明resolve()處,表明promise對象由pending狀態轉變為rejected。
3.notify(value) :在聲明notify()處,表明promise對象unfulfilled狀態,在resolve或reject之前可以被多次調用。

2.deffered 對象屬性

promise :最後返回的是一個新的deferred對象 promise 屬性,而不是原來的deferred對象。這個新的Promise對象只能觀察原來Promise對象的狀態,而無法修改deferred對象的內在狀態可以防止任務狀態被外部修改。

3.Promise API

當創建 deferred 實例時會創建一個新的 promise 對象,並可以通過 deferred.promise 得到該引用。

promise 對象的目的是在 deferred 任務完成時,允許感興趣的部分取得其執行結果。

4.promise 對象的方法

1.then(errorHandler, fulfilledHandler, progressHandler):then方法用來監聽一個Promise的不同狀態。errorHandler監聽failed狀態,fulfilledHandler監聽fulfilled狀態,progressHandler監聽unfulfilled(未完成)狀態。此外,notify 回調可能被調用 0到多次,提供一個進度指示在解決或拒絕(resolve和rejected)之前。

2.catch(errorCallback) —— promise.then(null, errorCallback) 的快捷方式

3.finally(callback) ——讓你可以觀察到一個 promise 是被執行還是被拒絕, 但這樣做不用修改最後的 value值。 這可以用來做一些釋放資源或者清理無用對象的工作,不管promise 被拒絕還是解決。 

 

q常用的幾個方法:

  • defer() 創建一個deferred對象,這個對象可以執行幾個常用的方法,比如resolve,reject,notify等
  • all() 傳入Promise的數組,批量執行,返回一個promise對象
  • when() 傳入一個不確定的參數,如果符合Promise標準,就返回一個promise對象。 

all()方法

當批量的執行某些方法時,就可以使用這個方法。有了all,你就可以並行執行多個非同步操作,並且在一個回調中處理所有的返回數據。

用Promise.all來執行,all接收一個數組參數,裡面的值最終都算返回Promise對象。這樣,三個非同步操作的並行執行的,等到它們都執行完後才會進到then裡面

那麼,三個非同步操作返回的數據哪裡去了呢?都在then裡面呢,all會把所有非同步操作的結果放進一個數組中傳給then,就是 下麵的results。所以下麵代碼的輸出結果就是:

            var funcA = function(){
                console.log("funcA");
                return "hello,funA";
            }
            var funcB = function(){
                console.log("funcB");
                return "hello,funB";
            }
            $q.all([funcA(),funcB()])
            .then(function(result){
                console.log(result);
            });

執行的結果:

funcA
funcB
Array [ "hello,funA", "hello,funB" ] 

when()方法

when方法中可以傳入一個參數,這個參數可能是一個值,可能是一個符合promise標準的外部對象。

            var funcA = function(){
                console.log("funcA");
                return "hello,funA";
            }
            $q.when(funcA())
            .then(function(result){
                console.log(result);
            });

當傳入的參數不確定時,可以使用這個方法。

hello,funA

 

四、鏈式請求

通過then()方法可以實現promise鏈式調用,因為then方法總是返回一個新的promise。

runAsync1()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return runAsync3();
})
.then(function(data){
    console.log(data);
});
function runAsync1(){
    var p = new Promise(function(resolve, reject){
        //做一些非同步操作
        setTimeout(function(){
            console.log('非同步任務1執行完成');
            resolve('隨便什麼數據1');
        }, 1000);
    });
    return p;            
}
function runAsync2(){
    var p = new Promise(function(resolve, reject){
        //做一些非同步操作
        setTimeout(function(){
            console.log('非同步任務2執行完成');
            resolve('隨便什麼數據2');
        }, 2000);
    });
    return p;            
}
function runAsync3(){
    var p = new Promise(function(resolve, reject){
        //做一些非同步操作
        setTimeout(function(){
            console.log('非同步任務3執行完成');
            resolve('隨便什麼數據3');
        }, 2000);
    });
    return p;            
}

運行結果:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在實際開發過程中經常在按鈕上添加文字和圖片,位置和圖片的位置根據需求放置也是不一樣的。下麵實現了各種顯示方式,如下圖: UIButton+LSAdditions.h UIButton+LSAdditions.m 現在測試代碼如下: ...
  • 崩潰分析方式:命令行解析Crash文件 通過Mac自帶的命令行工具解析Crash文件需要具備三個文件 symbolicatecrash,Xcode自帶的崩潰分析工具,使用這個工具可以更精確的定位崩潰所在的位置,將0x開頭的地址替換為響應的代碼和具體行數。 我們打包時產生的dSYM文件。 崩潰時產生的 ...
  • id類型是一個通用類型,OC使用id表示任意類型的對象,它可以作為一個占位符表示這是一個不確定的類型的對象或者引用。因此,所有的對象都 可以用id來表示。這很有用,想象一下,如果你需要實現一個通用的鏈表類,你可以將鏈表結點中的數據欄位的類型聲明為id類型,那麼你就可以往這個鏈表中存放任意類型的對象了 ...
  • textView用於顯示文本,大量文字顯示在一起顯得過於緊湊。可通過在佈局中更改TextView屬性設置行間距。 1、android:lineSpacingMultiplier="1.5" 表示1.5倍行距 2、android:lineSpacingExtra="3dp" 表示行間距離為3dp 有時 ...
  • 作者:ManfredHu 鏈接:http://www.manfredhu.com/2018/03/15/31-laya-game-tips/index.html 聲明:版權所有,轉載請保留本段信息,謝謝大家 LayaBox Web前端最近都在跨界!!現在又伸手到游戲領域了。但是真的那麼好跨界嗎?請讓 ...
  • 之前在看對象的api中for in函數時,有一個地方讓我略有疑惑: 為什麼是obj[key]而不是obj.key呢?我們在瀏覽器試一下: 說起來也有點尷尬,原來在for in函數中,得到的key是一個字元串類型,所以只能用obj[key],其實,比如說在這個對象中,obj.x和obj["x"]是完全 ...
  • 前言:這是筆者學習之後自己的理解與整理。如果有錯誤或者疑問的地方,請大家指正,我會持續更新! AJAX 是 asynchronous javascript and XML 的簡寫,就是非同步的 javascript 和 XML。這一技術能夠向伺服器請求額外的數據而無須刷新整個頁面,會帶來更好的用戶體驗 ...
  • 1. ng-init 屬性: 2. ng-selected 屬性: <html><head></head><body> <!--<input type="text" ng-model="good.factory" title="{{good.factory}}">--> <select class= ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...