Javacript和AngularJS中的Promises

?

promise是Javascript異步編程很好的解決方案。對于一個異步方法,執行一個回調函數。

比如頁面調用google地圖的api時就使用到了promise。

?

function success(position){var cords = position.coords;console.log(coords.latitude + coords.longitude);
}function error(err){console.warn(err.code+err.message)
}navigator.geolocation.getCurrentPosition(success, error);

?

■ 如何處理多個異步方法

如果有很多異步方法需要按序執行呢?async1(success, failure), async2(success, failure), ...asyncN(success, failure),該如何處理呢?

最簡單的,可能會這樣寫:

?

async1(function(){async2(function(){...asyncN(null, null);...}, null)
}, null)

?

以上的代碼是比較難維護的。

我們可以讓所有的異步方法執行完畢后出來一個通知。

?

var counter = N;
function success(){counter--;if(counter === 0){alert('done');}
}async1(success);
async2(success);
...
asyncN(success);

?

■ 什么是Promise和Deferred

deferred表示異步操作的結果,提供了一個顯示操作結果和狀態的接口,并提供了一個可以獲取該操作結果相關的promise實例。deferred是可以改變操作狀態的。

promise提供了一個用來和相關deferred交互的接口。

當創建一個deferred,相當于一個pending狀態;
當執行resolve方法,相當于一個resolved狀態。
當執行reject方法,相當于一個rejected狀態。

我們可以在創建deferred之后,定義回調函數,而回調函數在得到resolved和rejected的狀態提示后開始執行。異步方法不需要知道回調函數如何操作,只需要在得到resolved或rejected狀態后通知回調函數開始執行。

■ 基本用法

→ 創建deferred

var myFirstDeferred = $q.defer();

這里,對于myFirstDeferred這個deferred,狀態是pending,接下來,當異步方法執行成功,狀態變成resolved,當異步方法執行失敗,狀態變成rejected。

→ Resolve或Reject這個dererred

假設有這樣的一個異步方法:async(success, failure)

?

async(function(value){myFirstDeferred.resolve(value);
}, function(errorReason){myFirstDeferred.reject(errorReason);
})

?

在AngularJS中,$q的resolve和reject不依賴上下文,大致可以這樣寫:

async(myFirstDeferred.resolve, myFirstDeferred.reject);

→ 使用deferred中的promise

var myFirstPromise = myFirstDeferred.promise;myFirstPromise.then(function(data){}, function(error){})

?

deferred可以有多個promise.

?

var anotherDeferred = $q.defer();anotherDeferred.promise.then(function(data){},function(error){})//調用異步方法
async(anotherDeferred.resolve, anotherDeferred.reject);anotherDeferred.promise.then(function(data){}, function(error){})

?

以上,如果異步方法async成功執行,兩個success方法都會被調用。

→ 通常把異步方法包裹到一個函數中

?

function getData(){var deferred = $q.defer();async(deferred.resolve,deferred.reject);return deferred.promise;
}//deferred的promise屬性記錄了達到resolved, reject狀態所需要執行的success和error方法
var dataPromise = getData();
dataPromise.then(function(data){console.log('success');}, function(error){console.log('error');})

?

如果只關注success回調函數該如何寫呢?

dataPromise.then(function(data){console.log('success');})

?

如果只關注error回調函數該如何寫呢?

dataPromise.then(null, function(error){console.log('error');})或dataPromise.catch(function(error){console.log('error');
})

?

如果不管回調成功或失敗都返回相同的結果呢?

var finalCallback = function(){console.log('不管回調成功或失敗都返回這個結果');
}dataPromise.then(finalCallback, finalCallback);或dataPromise.finally(finalCallback);

■ 值鏈式

假設有一個異步方法,使用deferred.resolve返回一個值。

function async(value){var deferred = $q.defer();var result = value / 2;deferred.resolve(result);return deferred.promise;
}

?

既然返回的是promise,我們就可以不斷then, then下去的。

var promise = async(8).then(function(x){return x+1;}).then(function(x){return x*2;})promise.then(function(x){console.log(x);
})  

以上,resolve出的值成為每一個鏈式的實參。

■ Promise鏈式

?

function async1(value){var deferred = $q.defer();var result = value * 2;deferred.resolve(result);return deferred.promise;
}function async2(value){var deferred = $q.defer();var result = value + 1;deferred.resolve(result);return deferred.promise;
}var promise = async1(10).then(function(x){return async2(x);})promise.then(function(x){console.log(x);
}) 

?

當然一種更易讀的寫法是:

function logValue(value){console.log(value);
}async1(10).then(async2).then(logValue);

?

async1方法的返回值成為then方法中的success方法中的實參。

如果從捕獲異常的角度,還可以這樣寫:

async1().then(async2).then(async3).catch(handleReject).finally(freeResources);

?

■ $q.reject(reason)?? ?

使用該方法能夠讓deferred呈現error狀態,并給出一個出現error的理由。

var promise = async().then(function(value){if(true){return value;} else {return $q.reject('value is not satisfied');}
})

?

■ $q.when(value)

返回一個promise并帶上值。

function getDataFromBackend(query){var data = searchInCache(query);if(data){return $q.when(data);} else {reutrn makeAasyncBackendCall(query);}
}

?

■ $q.all(promisesArr)

等待所有promise執行完成。

var allPromise = $q.all([async1(),async2(),...asyncN();
])allProise.then(function(values){var value1 = values[0],value2 = values[1],...valueN = values[N];console.log('all done');
})

?

轉載于:https://www.cnblogs.com/darrenji/p/5184733.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447934.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447934.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447934.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

男人沉默的真實原因

英國社會學家馬克經過調查發現:男人每天的說話量,是女人的一半。但男人們也大多用于朋友圈中、工作中,而與愛人的聊天交流,每天可能不足15分鐘,用詞量不超過10%。 其實,男人有很多緘默的方法,每…

Visual Studio 使用說明文檔、VScode 使用手冊

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 我只是記錄下地址,方便自已以后查看: Visual Studio 使用文檔 內容如:

JAVA File的創建及相對路徑絕對路徑

JAVA File的創建及相對路徑絕對路徑 轉載自 http://blog.sina.com.cn/s/blog_9386f17b0100w2vv.htmlFile f new File("D:/test/mytest.txt");//當執行這句話后在內存的棧空間存在一個f的應用,在堆空間里存在一個mytest.txt對象。注意 這個對象只含有文件…

腎有多好人就有多年輕 男女通用的補腎秘方

每天都堅持喝一碗,現在已經連續喝了三個多星期了,以前有好些白發的地方居然沒有復發,而且現在一根也沒有啊,我真的很開心。不僅白頭發不見了,而且皮膚變白皙和光滑了好多,氣色也比原來好了!好東西要大家分享…

Object.keys() Object.values()

Object.keys() //返回對象中各個鍵值對的鍵(key) Object.values() //返回對象中各個鍵值對的值(value) var obj { foo: "bar", baz: 42 };Object.keys(obj) // ["foo", "baz"]Object.values(obj) // ["ba…

vue 解決: *!!vue-style-loader!css-loader?{“sourceMap“:true}!../../../../vue-loader

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 問題描述 *!!vue-style-loader!css-loader?{“sourceMap”:true}!../../../../vue-loader/lib/style-compiler/index?{“vue”:true,…

計算機專業 程序員技術練級攻略(轉載)

程序員技術練級攻略轉載自: https://coolshell.cn/articles/4990.html 前言 你是否覺得自己從學校畢業的時候只做過小玩具一樣的程序?走入職場后哪怕沒有什么經驗也可以把以下這些課外練習走一遍(朋友的抱怨:學校課程總是從理論出發&#xff…

35 歲之前不應該錯過的 30 本書

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 PS:在這個書目中,我不偏好的書會直接放到最后,所以不是按原文順序來。 1、《目送》 作者&#xff1a…

生活中意想不到的妙招

1、抹布變白 抹布是咱們家中最常見的東西,干家務絕對離不開它,擦桌椅板凳,擦灶臺,油煙機,浴室,電器等等,家里總需要準備很多抹布,最難清理的恐怕就是廚房的抹布了吧?因為總是和油污…

“ 紫手環的力量 ” :我想,美好的生活應該是自已造就的...

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 我想或許我可以試試這個方法: 其實 我是真的打算試試,最近總是會憂慮,或許我應該自已努力給自已造就…

通過界面生成時不存在的數據刷新界面引起的卡頓問題

今天遇到了一個問題,就是有一個界面,在生成時之前請求數據,在界面中通過schedule 與unschedule不停查看本地是否收到此數據(通過發起request的Id),當收到之后刷新。 然后就引起了一個問題。界面彈出是有動畫…

解決 VUE:[WDS] Errors while compiling. Reload prevented...- invalid expression: Unexpected token -- in

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 1. 在網上找了個組件,直接把代碼放入自已的項目中報錯,提示信息如黑框中: 2. 此組件原碼就是這樣用的…

長壽的十個秘訣 至少選擇一個堅持實施

人人都想提高自己健康長壽的機率。下面的十個秘訣中,哪怕只選擇一個,然后堅持實施,若干年后你會發現已經受益無窮。 1、喝茶 喝茶,特別是喝綠茶,其中的抗氧化劑可以抵擋有害物質對你身體的傷害。喝茶被證明可以減壓…

vue中的slot插槽

1.無名插槽<body><div id"app">123</div><script src"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script type"text/javascript">//注冊組件Vue.component("my-component",{templ…

linux 上 日志中查異常,指定顯示異常前后日志內容

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 查異常cat -n abc.log |grep Exception|more如找到行數為&#xff1a;5201314行&#xff0c;再查看該行前后的異常信息cat -n abc.log |…

my40_MySQL鎖概述之意向鎖

本文在鎖概述的基礎上&#xff0c;通常實驗舉例&#xff0c;詳細地介紹了意向鎖的原理。 鎖范圍 全局鎖&#xff08;global lock&#xff09;表鎖&#xff08;table lock&#xff09;行鎖 (row lock) ROW LOCK的粒度LOCK_REC_NOG_GAP, record lock with out gap lockLOCK_GAP&…

C語言的整型溢出問題

整型溢出有點老生常談了&#xff0c;bla, bla, bla… 但似乎沒有引起多少人的重視。整型溢出會有可能導致緩沖區溢出&#xff0c;緩沖區溢出會導致各種黑客攻擊&#xff0c;比如最近OpenSSL的heartbleed事件&#xff0c;就是一個buffer overread的事件。在這里寫下這篇文章&…

石牌村中的美好 ...

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 看了下我這些天的吃的&#xff0c;好像天天是盒飯 ... 不過 2 葷 2 素 11 元&#xff0c;大概是城中村才會這么便宜吧 。 村里有很多…

警惕 十種短命的生活方式

“忙忙忙&#xff0c;忙到白了頭”。忙碌的白領階層在“金錢”與“健康”的物物交換中&#xff0c;損失掉的是什么呢? 究竟是什么在日復一日地蠶食白領們的生命? 危險方式1&#xff1a;極度缺乏體育鍛煉 在932名被調查者中&#xff0c;只有96人每周都固定時間鍛煉&#xff…

Thymeleaf 簡介、教程

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Thymeleaf是一個適用于Web和獨立環境的現代服務器端Java模板引擎。 Thymeleaf的主要目標是為您的開發工作流程帶來優雅的自然模板 - 可…