Angularjs Promise實(shí)例詳解
一、什么是Promise
Promise是對(duì)象,代表了一個(gè)函數(shù)最終可能的返回值或拋出的異常,就是用來(lái)異步處理值的。
Promise是一個(gè)構(gòu)造函數(shù),自己身上有all、reject、resolve這幾個(gè)異步方式處理值的方法,原型上有then、catch等同樣很眼熟的方法。
二、為什么使用Promise
有了Promise對(duì)象,就可以把異步操作以同步操作的流程表達(dá)出來(lái),避免了層層嵌套的回調(diào)函數(shù)。此外,Promise對(duì)象提供了統(tǒng)一的接口,使得控制異步操作更加容易。
Promise對(duì)象有以下2個(gè)特點(diǎn):
1.對(duì)象的狀態(tài)不受外界影響。
Promise對(duì)象代表一個(gè)異步操作,有三種狀態(tài):Pending(進(jìn)行中)、Resolved(已完成)和Rejected(已失敗)。只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無(wú)法改變這個(gè)狀態(tài)。
2.一旦狀態(tài)改變,就不會(huì)再變,任何時(shí)候都可以得到這個(gè)結(jié)果。
Promise對(duì)象的狀態(tài)改變,只有兩種可能:從Pending變?yōu)镽esolved;從Pending變?yōu)镽ejected。只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會(huì)再變了,會(huì)一直保持這個(gè)結(jié)果。
三、如何創(chuàng)建一個(gè)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服務(wù)
q服務(wù)是AngularJS中自己封裝實(shí)現(xiàn)的一種Promise實(shí)現(xiàn)。
要?jiǎng)?chuàng)建一個(gè)deferred對(duì)象,可以調(diào)用defer()方法:
var deferred = $q.defer(); //deffered上面暴露了三個(gè)方法,以及一個(gè)可以用于處理promise的promise屬性。 //promise屬性里面又包含了then、catch、finally三個(gè)方法

在Promise中,定義了三種狀態(tài):等待狀態(tài),完成狀態(tài),拒絕狀態(tài)。
deffered API
1.deffered 對(duì)象的方法
1.resolve(value):在聲明resolve()處,表明promise對(duì)象由pending狀態(tài)轉(zhuǎn)變?yōu)閞esolve。
2.reject(reason):在聲明resolve()處,表明promise對(duì)象由pending狀態(tài)轉(zhuǎn)變?yōu)閞ejected。
3.notify(value) :在聲明notify()處,表明promise對(duì)象unfulfilled狀態(tài),在resolve或reject之前可以被多次調(diào)用。
2.deffered 對(duì)象屬性
promise :最后返回的是一個(gè)新的deferred對(duì)象 promise 屬性,而不是原來(lái)的deferred對(duì)象。這個(gè)新的Promise對(duì)象只能觀察原來(lái)Promise對(duì)象的狀態(tài),而無(wú)法修改deferred對(duì)象的內(nèi)在狀態(tài)可以防止任務(wù)狀態(tài)被外部修改。
3.Promise API
當(dāng)創(chuàng)建 deferred 實(shí)例時(shí)會(huì)創(chuàng)建一個(gè)新的 promise 對(duì)象,并可以通過(guò) deferred.promise 得到該引用。
promise 對(duì)象的目的是在 deferred 任務(wù)完成時(shí),允許感興趣的部分取得其執(zhí)行結(jié)果。
4.promise 對(duì)象的方法
1.then(errorHandler, fulfilledHandler, progressHandler):then方法用來(lái)監(jiān)聽(tīng)一個(gè)Promise的不同狀態(tài)。errorHandler監(jiān)聽(tīng)failed狀態(tài),fulfilledHandler監(jiān)聽(tīng)fulfilled狀態(tài),progressHandler監(jiān)聽(tīng)unfulfilled(未完成)狀態(tài)。此外,notify 回調(diào)可能被調(diào)用 0到多次,提供一個(gè)進(jìn)度指示在解決或拒絕(resolve和rejected)之前。
2.catch(errorCallback) —— promise.then(null, errorCallback) 的快捷方式
3.finally(callback) ——讓你可以觀察到一個(gè) promise 是被執(zhí)行還是被拒絕, 但這樣做不用修改最后的 value值。 這可以用來(lái)做一些釋放資源或者清理無(wú)用對(duì)象的工作,不管promise 被拒絕還是解決。
q常用的幾個(gè)方法:
- defer() 創(chuàng)建一個(gè)deferred對(duì)象,這個(gè)對(duì)象可以執(zhí)行幾個(gè)常用的方法,比如resolve,reject,notify等
- all() 傳入Promise的數(shù)組,批量執(zhí)行,返回一個(gè)promise對(duì)象
- when() 傳入一個(gè)不確定的參數(shù),如果符合Promise標(biāo)準(zhǔn),就返回一個(gè)promise對(duì)象。
all()方法
當(dāng)批量的執(zhí)行某些方法時(shí),就可以使用這個(gè)方法。有了all,你就可以并行執(zhí)行多個(gè)異步操作,并且在一個(gè)回調(diào)中處理所有的返回?cái)?shù)據(jù)。
用Promise.all來(lái)執(zhí)行,all接收一個(gè)數(shù)組參數(shù),里面的值最終都算返回Promise對(duì)象。這樣,三個(gè)異步操作的并行執(zhí)行的,等到它們都執(zhí)行完后才會(huì)進(jìn)到then里面。
那么,三個(gè)異步操作返回的數(shù)據(jù)哪里去了呢?都在then里面呢,all會(huì)把所有異步操作的結(jié)果放進(jìn)一個(gè)數(shù)組中傳給then,就是 下面的results。所以下面代碼的輸出結(jié)果就是:
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);
});
執(zhí)行的結(jié)果:
funcA funcB Array [ "hello,funA", "hello,funB" ]
when()方法
when方法中可以傳入一個(gè)參數(shù),這個(gè)參數(shù)可能是一個(gè)值,可能是一個(gè)符合promise標(biāo)準(zhǔn)的外部對(duì)象。
var funcA = function(){
console.log("funcA");
return "hello,funA";
}
$q.when(funcA())
.then(function(result){
console.log(result);
});
當(dāng)傳入的參數(shù)不確定時(shí),可以使用這個(gè)方法。
hello,funA
四、鏈?zhǔn)秸?qǐng)求
通過(guò)then()方法可以實(shí)現(xiàn)promise鏈?zhǔn)秸{(diào)用,因?yàn)閠hen方法總是返回一個(gè)新的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('異步任務(wù)1執(zhí)行完成');
resolve('隨便什么數(shù)據(jù)1');
}, 1000);
});
return p;
}
function runAsync2(){
var p = new Promise(function(resolve, reject){
//做一些異步操作
setTimeout(function(){
console.log('異步任務(wù)2執(zhí)行完成');
resolve('隨便什么數(shù)據(jù)2');
}, 2000);
});
return p;
}
function runAsync3(){
var p = new Promise(function(resolve, reject){
//做一些異步操作
setTimeout(function(){
console.log('異步任務(wù)3執(zhí)行完成');
resolve('隨便什么數(shù)據(jù)3');
}, 2000);
});
return p;
}
運(yùn)行結(jié)果:

總結(jié)
以上所述是小編給大家介紹的Angularjs Promise實(shí)例詳解,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Angular應(yīng)用打包和部署實(shí)現(xiàn)過(guò)程詳解
這篇文章主要為大家介紹了Angular應(yīng)用打包和部署實(shí)現(xiàn)過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
解決angularJS中input標(biāo)簽的ng-change事件無(wú)效問(wèn)題
今天小編就為大家分享一篇解決angularJS中input標(biāo)簽的ng-change事件無(wú)效問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
AngularJs中$cookies簡(jiǎn)單用法分析
這篇文章主要介紹了AngularJs中$cookies簡(jiǎn)單用法,結(jié)合實(shí)例形式分析了AngularJS使用$cookies存儲(chǔ)變量相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2019-05-05
Angular 4.x 動(dòng)態(tài)創(chuàng)建表單實(shí)例
本篇文章主要介紹了Angular 4.x 動(dòng)態(tài)創(chuàng)建表單實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
Angular.js中用ng-repeat-start實(shí)現(xiàn)自定義顯示
大家都知道Angular.js可以用ng-repeat來(lái)顯示列表數(shù)據(jù),可是如果想要自定義顯示數(shù)據(jù)列表的話ng-repeat就實(shí)現(xiàn)不了了,這個(gè)時(shí)候可以利用ng-repeat-start 和 ng-repeat-end來(lái)實(shí)現(xiàn),下面通過(guò)本文來(lái)詳細(xì)看看實(shí)現(xiàn)的方法吧。2016-10-10
Angular6 用戶自定義標(biāo)簽開(kāi)發(fā)的實(shí)現(xiàn)方法
這篇文章主要介紹了Angular6 用戶自定義標(biāo)簽開(kāi)發(fā)的實(shí)現(xiàn)方法,下面我們就通過(guò)一個(gè)簡(jiǎn)單的例子演示Angular6中的這一新功能,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,需要的朋友可以參考下2019-01-01
淺談angular2的http請(qǐng)求返回結(jié)果的subcribe注意事項(xiàng)
下面小編就為大家?guī)?lái)一篇淺談angular2的http請(qǐng)求返回結(jié)果的subcribe注意事項(xiàng)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03

