## 形象的講解angular中的$q與promise
`promise`不是angular首創(chuàng)的,作為一種編程模式,它出現(xiàn)在……1976年,比JavaScript還要古老得多。`promise`全稱(chēng)是 Futures and `promises`。具體的可以參見(jiàn) http://en.wikipedia.org/wiki/Futures_and_promises 。
而在javascript世界中,一個(gè)廣泛流行的庫(kù)叫做Q 地址是https://github.com/kriskowal/q 而angular中的$q就是從它引入的。`promise`解決的是異步編程的問(wèn)題,對(duì)于生活在同步編程世界中的程序員來(lái)說(shuō),它可能比較難于理解,這也構(gòu)成了angular入門(mén)門(mén)檻之一,本文將用生活中的一個(gè)例子對(duì)此做一個(gè)形象的講解。
假設(shè)有一個(gè)家具廠,而它有一個(gè)VIP客戶張先生。
有一天張先生需要一個(gè)豪華衣柜,于是,他打電話給家具廠說(shuō)我需要一個(gè)衣柜,回頭做好了給我送來(lái),這個(gè)操作就叫`$q.defer`,也就是延期,因?yàn)檫@個(gè)衣柜不是現(xiàn)在要的,所以張先生這是在發(fā)起一個(gè)可延期的請(qǐng)求。
同時(shí),家具廠給他留下了一個(gè)回執(zhí)號(hào),并對(duì)他說(shuō):我們做好了會(huì)給您送過(guò)去,放心吧。這叫做`promise`,也就是承諾。
這樣,這個(gè)defer算是正式創(chuàng)建了,于是他把這件事記錄在自己的日記上,并且同時(shí)記錄了回執(zhí)號(hào),這叫做`deferred`,也就是已延期事件。
現(xiàn)在,張先生就不用再去想著這件事了,該做什么做什么,這就是“異步”的含義。
假設(shè)家具廠在一周后做完了這個(gè)衣柜,并如約送到了張先生家(包郵哦,親),這就叫做`deferred.resolve(衣柜)`,也就是“已解決”。而這時(shí)候張先生只要簽收一下這個(gè)(衣柜)參數(shù)就行了,當(dāng)然,這個(gè)“郵包”中也不一定只有衣柜,還可以包含別的東西,比如廠家宣傳資料、產(chǎn)品名錄等。整個(gè)過(guò)程中輕松愉快,誰(shuí)也沒(méi)等誰(shuí),沒(méi)有浪費(fèi)任何時(shí)間。
假設(shè)家具廠在評(píng)估后發(fā)現(xiàn)這個(gè)規(guī)格的衣柜我們做不了,那么它就需要`deferred.reject(理由)`,也就是“拒絕”。拒絕沒(méi)有時(shí)間限制,可以發(fā)生在給出承諾之后的任何時(shí)候,甚至可能發(fā)生在快做完的時(shí)候。而且拒絕時(shí)候的參數(shù)也不僅僅限于理由,還可以包含一個(gè)道歉信,違約金之類(lèi)的,總之,你想給他什么就給他什么,如果你覺(jué)得不會(huì)惹惱客戶,那么不給也沒(méi)關(guān)系。
假設(shè)家具廠發(fā)現(xiàn),自己正好有一個(gè)符合張先生要求的存貨,它就可以用`$q.when(現(xiàn)有衣柜)`來(lái)把這個(gè)承諾給張先生,這件事就立即被解決了,皆大歡喜,張先生可不在乎你是從頭做的還是現(xiàn)有的成品,只會(huì)驚嘆于你們的效率之高。
假設(shè)這個(gè)家具廠對(duì)客戶格外的細(xì)心,它還可能通過(guò)`deferred.notify(進(jìn)展情況)`給張先生發(fā)送進(jìn)展情況的“通知”。
這樣,整個(gè)異步流程就圓滿完成,無(wú)論成功或者失敗,張先生都沒(méi)有往里面投入任何額外的時(shí)間成本。
好,我們?cè)贁U(kuò)展一下這個(gè)故事:
張先生這次需要做一個(gè)桌子,三把椅子,一張席夢(mèng)思,但是他不希望今天收到個(gè)桌子,明天收到個(gè)椅子,后天又得簽收一次席夢(mèng)思,而是希望家具廠做好了之后一次性送過(guò)來(lái),但是他下單的時(shí)候又是分別下單的,那么他就可以重新跟家具廠要一個(gè)包含上述三個(gè)承諾的新承諾,這就是`$q.all(桌子承諾,椅子承諾,席夢(mèng)思承諾)`,這樣,他就不用再關(guān)注以前的三個(gè)承諾了,直接等待這個(gè)新的承諾完成,到時(shí)候只要一次性簽收了前面的這些承諾就行了。
> 雪狼http://www.ngnice.com/posts/126ee9cf6ddb68
- 步入JavaScript的世界
- 二進(jìn)制運(yùn)算
- JavaScript 的版本是怎么回事?
- JavaScript和DOM的產(chǎn)生與發(fā)展
- DOM事件處理
- js的并行加載與順序執(zhí)行
- 正則表達(dá)式
- 當(dāng)遇上this時(shí)
- Javascript中apply、call、bind
- JavaScript的編譯過(guò)程與運(yùn)行機(jī)制
- 執(zhí)行上下文(Execution Context)
- javascript 作用域
- 分組中的函數(shù)表達(dá)式
- JS之constructor屬性
- Javascript 按位取反運(yùn)算符 (~)
- EvenLoop 事件循環(huán)
- 異步編程
- JavaScript的九個(gè)思維導(dǎo)圖
- JavaScript奇淫技巧
- JavaScript:shim和polyfill
- ===值得關(guān)注的庫(kù)===
- ==文章==
- JavaScript框架
- Angular 1.x
- 啟動(dòng)引導(dǎo)過(guò)程
- $scope作用域
- $q與promise
- ngRoute 和 ui-router
- 雙向數(shù)據(jù)綁定
- 規(guī)范和性能優(yōu)化
- 自定義指令
- Angular 事件
- lodash
- Test
