日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
什么是Promises的重點(diǎn)

迄今為止,可能每個(gè)JavaScript開發(fā)者和他們的祖母都聽說過Promises。如果你沒有,那么你即將會(huì)。promises的概念是由CommonJS小組的成員在 Promises/A規(guī)范 中提出來的。Promises被逐漸用作一種管理異步操作回調(diào)的方法,但出于它們的設(shè)計(jì),它們遠(yuǎn)比那個(gè)有用得多。事實(shí)上,由于它們的多種用法,有無數(shù)人告訴我——在我寫過一些關(guān)于promises的東西后——我“遺漏了promises的重點(diǎn)”。那么什么是promises的重點(diǎn)呢?

創(chuàng)新互聯(lián)專注于中大型企業(yè)的成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站和網(wǎng)站改版、網(wǎng)站營銷服務(wù),追求商業(yè)策劃與數(shù)據(jù)分析、創(chuàng)意藝術(shù)與技術(shù)開發(fā)的融合,累計(jì)客戶千余家,服務(wù)滿意度達(dá)97%。幫助廣大客戶順利對(duì)接上互聯(lián)網(wǎng)浪潮,準(zhǔn)確優(yōu)選出符合自己需要的互聯(lián)網(wǎng)運(yùn)用,我們將一直專注成都品牌網(wǎng)站建設(shè)和互聯(lián)網(wǎng)程序開發(fā),在前進(jìn)的路上,與客戶一起成長!

一點(diǎn)關(guān)于Promises的東西

在我開始promise的“重點(diǎn)”之前,我想我應(yīng)該給你一點(diǎn)它們?nèi)绾喂ぷ鞯膬?nèi)貌。一個(gè)promise是一個(gè)對(duì)象——根據(jù)Promise/A規(guī)范——只需要一個(gè)方法:then。then方法帶有三個(gè)參數(shù):一個(gè)成功回調(diào),一個(gè)失敗回調(diào),和一個(gè)前進(jìn)回調(diào)(規(guī)范沒有要求包括前進(jìn)回調(diào)的實(shí)現(xiàn),但是很多都實(shí)現(xiàn)了)。一個(gè)全新的promise對(duì)象從每個(gè)then的調(diào)用中返回。

一個(gè)promise可以是三種狀態(tài)之一:未完成的,完成的,或者失敗的。promise以未完成的狀態(tài)開始,如果成功它將會(huì)是完成態(tài),如果失敗將會(huì)是失敗態(tài)。當(dāng)一個(gè)promise移動(dòng)到完成態(tài),所有注冊(cè)到它的成功回調(diào)將被調(diào)用,而且會(huì)將成功的結(jié)果值傳給它。另外,任何注冊(cè)到promise的成功回調(diào),將會(huì)在它已經(jīng)完成以后立即被調(diào)用。

同樣的事情發(fā)生在promise移動(dòng)到失敗態(tài)的時(shí)候,除了它調(diào)用的是失敗回調(diào)而不是成功回調(diào)。對(duì)包含前進(jìn)特性的實(shí)現(xiàn)來說,promise在它離開未完成狀態(tài)以前的任何時(shí)刻,都可以更新它的progress。當(dāng)progress被更新,所有的前進(jìn)回調(diào)(progress callbacks)會(huì)被傳遞以progress的值,并被立即調(diào)用。前進(jìn)回調(diào)被以不同于成功和失敗回調(diào)的方式處理;如果你在一個(gè)progress更新已經(jīng)發(fā)生以后注冊(cè)了一個(gè)前進(jìn)回調(diào),新的前進(jìn)回調(diào)只會(huì)在它被注冊(cè)以后被已更新的progress調(diào)用。

我們不會(huì)進(jìn)一步深入promise狀態(tài)是如何管理的,因?yàn)槟遣辉谝?guī)范之內(nèi),而且每個(gè)實(shí)現(xiàn)都有差別。在后面的例子中,你將會(huì)看到它是如何完成的,但目前這就是所有你需要知道的。

處理回調(diào)

像前面提到的為異步操作處理回調(diào),是promises的最基本和最普通的用途,讓我們將一個(gè)標(biāo)準(zhǔn)的回調(diào)與一個(gè)采用了promise的回調(diào)比較一下。

回調(diào)

 
 
 
  1. // Normal callback usage
  2. asyncOperation(function() {
  3.     // Here's your callback
  4. });
  5. // Now `asyncOperation` returns a promise
  6. asyncOperation().then(function(){
  7.     // Here's your callback
  8. });

我很懷疑只是看到這個(gè)例子的話是否有人會(huì)真的關(guān)心去使用promises??雌饋頉]有什么好處,除了“then”使得在異步操作完成之后的回調(diào)函數(shù)被調(diào)用這件事看起來更加明顯。但是即使是這個(gè)好處,我們現(xiàn)在有了更多的代碼(抽象應(yīng)該使我們的代碼更短,不是嗎?)而且promise比標(biāo)準(zhǔn)回調(diào)稍微性能差一點(diǎn)。

但是,不要讓這阻礙到你。如果這就是promise可以做的最好的事,這篇文章就不會(huì)存在了。

厄運(yùn)的金字塔

網(wǎng)上你可以找到很多文章引用“厄運(yùn)的金字塔”的說法作為使用promises的主要原因。這是指需要連續(xù)的執(zhí)行多個(gè)異步操作。在普通回調(diào)下,我們將會(huì)在相互的調(diào)用之間結(jié)束嵌套的調(diào)用;隨著這種調(diào)用代碼變得更縮進(jìn),生成了一個(gè)金字塔(指向右方的)因此有了“厄運(yùn)的金字塔”的名字。如果你只需連續(xù)執(zhí)行一兩個(gè)異步操作,那么這還不是太壞,但一旦你需要做3個(gè)或更多,它將會(huì)變得難以閱讀,特別是當(dāng)每一步都有相當(dāng)多的處理需要做的時(shí)候。使用promises可以幫助代碼變平,而且使它再一次變得更容易閱讀。我們來看看。

厄運(yùn)的金字塔

 
 
 
  1. // Normal callback usage => PYRAMID OF DOOOOOOOOM
  2. asyncOperation(function(data){
  3.     // Do some processing with `data`
  4.     anotherAsync(function(data2){
  5.         // Some more processing with `data2`
  6.         yetAnotherAsync(function(){
  7.             // Yay we're finished!
  8.         });
  9.     });
  10. });
  11. // Let's look at using promises
  12. asyncOperation()
  13. .then(function(data){
  14.     // Do some processing with `data`
  15.     return anotherAsync();
  16. })
  17. .then(function(data2){
  18.     // Some more processing with `data2`
  19.     return yetAnotherAsync();
  20. })
  21. .then(function(){
  22.     // Yay we're finished!
  23. });

正如你所見,promises的使用使得事情變扁平而且更可讀了。這能起作用是因?yàn)椤裨缦忍岬降摹猼hen返回了一個(gè)promise,所以你可以將then的調(diào)用不停的串連起來。由then返回的promise裝載了由調(diào)用返回的值。如果調(diào)用返回了一個(gè)promise(像這個(gè)例子中的情形一樣),then返回的 promise裝載了與你的回調(diào)返回的promise所裝載的相同值。這內(nèi)容很多,因此我將幫助你一步一步的理解它。

異步操作返回一個(gè)promise對(duì)象。因此我們?cè)谀莻€(gè)promise對(duì)象中調(diào)用then,并且傳給它一個(gè)回調(diào)函數(shù);then也會(huì)返回一個(gè)promise。當(dāng)異步操作結(jié)束,它將給promise裝上數(shù)據(jù)。然后(第一次)回調(diào)被調(diào)用,數(shù)據(jù)被作為參數(shù)傳遞進(jìn)去。如果回調(diào)不含有返回值,then返回的promise將會(huì)立即不帶值組裝。如果回調(diào)返回的不是一個(gè)promise,那么then返回的 promise將會(huì)立即裝載那個(gè)數(shù)值。如果回調(diào)返回一個(gè)promise(像例子中的),那么then返回的 promise將等待直到我們回調(diào)返回的promise被完全裝載。一旦我們回調(diào)的 promise被裝載,它裝載的值(本例中就是data2)將會(huì)被提交給then的promise。然后then中的promise裝載了data2。等等。聽起來有點(diǎn)復(fù)雜,但事實(shí)上很簡單,如果我說的你不能理解,我非常抱歉。我猜我可能不是談?wù)撍淖罴讶诉x。

用命名的回調(diào)替代

但顯然 promises 不是使這個(gè)結(jié)構(gòu)扁平化的唯一方法。在寫了一篇提到promises解決了厄運(yùn)的金字塔問題的帖子之后,有個(gè)人對(duì)該帖評(píng)論說……

我想promises有時(shí)是有用的,但是“嵌套”的回調(diào)的問題(圣誕樹綜合癥)可以僅用一個(gè)命名的函數(shù)作為一個(gè)參數(shù)替代匿名函數(shù)的方法平常的處理:

asyncCall( param1, param2, HandlerCallback );

function HandlerCallback(err, res){
// do stuff
}

它的例子只是給出了一層深的例子,但它仍是正確的。我們來擴(kuò)展我前面的例子,使這個(gè)看起來容易些。

命名回調(diào)

 
 
 
  1. // Normal callback usage => PYRAMID OF DOOOOOOOOM
  2. asyncOperation(handler1);
  3. function handler1(data) {
  4.     // Do some processing with `data`
  5.     anotherAsync(handler2);
  6. }
  7. function handler2(data2) {
  8.     // Some more processing with `data2`
  9.     yetAnotherAsync(handler3);
  10. }
  11. function handler3() {
  12.     // Yay we're finished!
  13. }

看看上面的代碼!他們絕對(duì)是對(duì)的!它就是一個(gè)扁平的結(jié)構(gòu),但是這里有個(gè)問題同樣也存在于 我以前從來沒有注意過的老的回調(diào)例子中:依賴性和復(fù)用性。依賴性和復(fù)用性是相互關(guān)聯(lián)的可逆類型。一樣?xùn)|西依賴的越少,那么它的復(fù)用性就越大。在以上的例子中,handler1依賴handler2,handler2依賴handler3.這就意味著handler1無論出于任何目的都不可在被用除非handler2也呈現(xiàn)出來。假如你不打算重用他們,那么給你的函數(shù)命名又有什么意義呢?

最糟糕的的是handler1都不關(guān)心在handler2里面發(fā)生了什么事情。它壓根就不需要handler2除了和它異步工作。因此,讓我們消除這些依賴性然后通過用promise使函數(shù)更具復(fù)用性。

#p#

鏈?zhǔn)交卣{(diào)

 
 
 
  1. asyncOperation().then(handler1).then(handler2).then(handler3);
  2. function handler1(data) {
  3.     // Do some processing with `data`
  4.     return anotherAsync();
  5. }
  6. function handler2(data2) {
  7.     // Some more processing with `data2`
  8.     return yetAnotherAsync();
  9. }
  10. function handler3() {
  11.     // Yay we're finished!
  12. }

這樣看起來是不是好多了?假如另外的函數(shù)存在的話,現(xiàn)在handler1和handler2都互不相關(guān)了。想看看他們是否真的很棒呢?現(xiàn)在handler1可以被用在不需要handler2的情況下了。相反,handler1被操作以后,我們將可以用另一個(gè)handler。

復(fù)用函數(shù)

 
 
 
  1. asyncOperation().then(handler1).then(anotherHandler);
  2. function handler1(data) {
  3.     // Do some processing with `data`
  4.     return anotherAsync();
  5. }
  6. function anotherHandler(data2) {
  7.     // Do some really awesome stuff that you've never seen before. It'll impress you
  8. }

現(xiàn)在handler1已經(jīng)從handler2脫離而且可以被用在了更多的情形中,特別是那些由handler2提供的功能而我們又不想用的。這就是復(fù)用性!評(píng)論家解決代碼易讀性的唯一方法就是通過消除縮進(jìn)。我們不想消除縮進(jìn)僅僅是為了縮進(jìn)。多層次的縮進(jìn)僅僅是某些事情錯(cuò)誤的標(biāo)志,問題不一定在它本身。他就像是由脫水引起的頭痛。真正的問題是脫水,不是頭痛。解決的方法是獲得水合物,而不是用一些止痛藥。

并行異步操作

在前面我提到的文章里,我將promises與events在處理異步操作方面做了比較。遺憾的是,按照那些曾提到過的人在評(píng)論里給的說法,我比較的不是很成功。我描述出了promises的力量,接著轉(zhuǎn)到events來描述它們的力量,就像在我的特別項(xiàng)目里用到的那樣。沒有比較和對(duì)比。一位評(píng)論者寫道(修改了一點(diǎn)語法錯(cuò)誤):

我想用帖子中的例子是一個(gè)壞的對(duì)照。有篇論文證明了promises的值將會(huì)怎樣,如果按下虛構(gòu)的“啟動(dòng)服務(wù)器按鈕”,將不僅僅是啟動(dòng)一個(gè)web服務(wù)器,還有一個(gè)數(shù)據(jù)庫服務(wù)器,當(dāng)它們都在運(yùn)行的時(shí)候只是更新了UI。

使用promise的.when方法將會(huì)使這種“多個(gè)異步操作”例子變得普通,然而響應(yīng)多個(gè)異步事件需要一個(gè)并不普通的代碼量。

他完全正確。事實(shí)上我沒有比較那兩種情況。那篇文章的要點(diǎn)實(shí)際在于說明promises不是異步操作的唯一機(jī)制,而且在一些情況下,它們也不一定是最好的。在這個(gè)評(píng)論者指出的情況下,promises當(dāng)然是最佳的解決辦法。我們來看看他說的是什么。

jQuery 具有 一個(gè)名為when的方法 ,可以帶上任意數(shù)量的promise參數(shù),并返回一個(gè)單一的promise。如果任何一個(gè)promise傳入失敗,when返回的promise也會(huì)失敗。如果所有的promises被裝載,那么每個(gè)值都將會(huì)按照promises被定義的順序傳遞給附加的回調(diào)。

以并行的方式執(zhí)行無數(shù)的異步操作非常有用,然后只要在它們之中的每一個(gè)結(jié)束之后繼續(xù)執(zhí)行回調(diào)。我們看一個(gè)簡單的例子.

jQuery.when

 
 
 
  1. // Each of these async functions return a promise
  2. var promise1 = asyncOperation1();
  3. var promise2 = asyncOperation2();
  4. var promise3 = asyncOperation3();
  5. // The $ refers to jQuery
  6. $.when(promise1, promise2, promise3).then(
  7.     function(value1, value2, value3){
  8.         // Do something with each of the returned values
  9.     }
  10. );

人們經(jīng)常說這是 promises 帶來的最好的東西之一,也是 promises 的一部分重要的意義所在。我也認(rèn)為這是個(gè)簡化了大量操作的好特性,但是這種 when 方法的機(jī)制 根本就沒有在任何 Promises 規(guī)范中提到,所以我不認(rèn)為它是 Promises意義所在。有一個(gè)規(guī)范提到了 when 方法,但是和上面的完全不同。就我所知,jQuery 是唯一的實(shí)現(xiàn)了這種 when 方法的庫。其他的 promises 庫,例如  Q, Dojo, 和  when 依照  Promises/B spec 實(shí)現(xiàn)了 when 方法, 但是并沒有實(shí)現(xiàn)注釋者提及的 when 方法。但是,Q 庫有一個(gè)   all方法,when.js 也有一個(gè)  parallel方法,與上面的 jQuery.when 方法作用一樣,只是它們接受一個(gè)數(shù)組類型的參數(shù),而不是任意數(shù)量的參數(shù)。

值的表示

另一個(gè)評(píng)論者給我留言:

Promise是處理以下場景的更好的方法:

"我想在這個(gè)數(shù)據(jù)庫中找一個(gè)用戶,但find方法是異步的。"

因此,這里我們有了一個(gè)不能立刻返回值的find方法。但最終它確實(shí)"返回"了一個(gè)數(shù)值(通過一個(gè)回調(diào)的方式),而你希望以某種方式處理那個(gè)數(shù)值?,F(xiàn)在,通過使用一個(gè)回調(diào),你能定義一個(gè)繼續(xù)部分,或者說“一些將在以后時(shí)間里處理那個(gè)數(shù)值的代碼”

Promise改變了那種“嘿,這里是一些你會(huì)發(fā)現(xiàn)你用來處理返回?cái)?shù)值的代碼”。它們是一些允許"find"方法說“嘿,我將忙著找你要找的信息,但與此同時(shí)你能繼續(xù)等著返回結(jié)果,而且你能同時(shí)以任何你希望的方式處理它,就像實(shí)際的東西!”

Promise代表了真實(shí)的數(shù)值。那就是陷阱。它們工作在你像處理實(shí)際東西一樣處理Promise的時(shí)候。Promise的JavaScript實(shí)現(xiàn)期待你給它傳遞一個(gè)回調(diào)函數(shù),這只是一個(gè)“巧合”,它不是重要的事情。

我相信這真的就是promise的重點(diǎn)。為什么?讀一讀 Promise/A規(guī)范 的第一句“一個(gè)promise代表了一個(gè)操作的一次完成最終返回的數(shù)值?!笆顾悬c(diǎn)明顯了,是不是?好吧,即使那就是重點(diǎn),那也不能阻止我在后面本文中呈現(xiàn)其他人的見解。不管怎么說,我們?cè)俣嗾務(wù)撨@個(gè)思想一點(diǎn)。

這個(gè)概念是美好的,但它在實(shí)踐中是如何體現(xiàn)的?把promises看作數(shù)值的表現(xiàn)形式看起來像什么?首先,讓我們來看看一些同步的代碼:

Synchronous Code

 
 
 
  1. // Search a collection for a list of "specific" items
  2. var dataArray = dataCollection.find('somethingSpecific');
  3. // Map the array so that we can get just the ID's
  4. var ids = map(dataArray, function(item){
  5.     return item.id;
  6. });
  7. // Display them
  8. display(ids);

好的,如果dataCollection.find是同步的,這段代碼能正常工作。但是如果它是異步的呢?我的意思是看看這段代碼;它完全是同步方式寫的。如果find是異步的,沒有方法能保證運(yùn)行正確,對(duì)不?不對(duì)。我們僅需修改map和display,接受promises作為參數(shù),代表用作計(jì)算的數(shù)據(jù)。同樣,find和map需要返回promises。所以假設(shè)dataCollectionque確實(shí)不包含數(shù)據(jù):僅僅只是調(diào)用AJAX獲取數(shù)據(jù)。所以現(xiàn)在將返回一個(gè)promise?,F(xiàn)在,讓我們重寫map和display,接受promises,但是我們?nèi)〔煌拿郑簆map和pdisplay。

#p#

接受Promise作為參數(shù)

 
 
 
  1. function pmap (dataPromise, fn) {
  2.     // Always assume `dataPromise` is a promise... cuts down on the code
  3.     // `then` returns a promise, so let's use that instead of creating our own
  4.     return dataPromise.then(
  5.         // Success callback
  6.         function(data) {
  7.             // Fulfill our promise with the data returned from the normal synchronous `map`
  8.             return map(data, fn);
  9.         }
  10.         // Pass errors through by not including a failure callback
  11.     );
  12. }
  13. function pdisplay(dataPromise) {
  14.     dataPromise.then(
  15.         // Success callback
  16.         function(data) {
  17.             // When we have the data, just send it to the normal synchronous `display`
  18.             display(data);
  19.         },
  20.         // Failure callback
  21.         function(err) {
  22.             // If it fails, we'll just display the error
  23.             display(err);
  24.         }
  25.     );
  26. }

這不會(huì)太難, 是嗎? 讓我們現(xiàn)在用這些新函數(shù)重新編寫上面那個(gè)例子:

異步代碼

 
 
 
  1. // Search a collection for a list of "specific" items
  2. var dataArray = dataCollection.find('somethingSpecific');
  3. // Map the array so that we can get just the ID's
  4. var ids = pmap(dataArray, function(item){
  5.     return item.id;
  6. });
  7. // Display them
  8. pdisplay(ids);

我所要做的是修改這些函數(shù)的名字。假如你很自信,你完全可以用相同的名字編寫這些函數(shù),接受一個(gè)promise或者普通值,做出相應(yīng)的反應(yīng)。在新代碼中,這些promise表示返回的最終值,所以我們能以promise看起來像真實(shí)值的方式來編寫代碼。

我撒了點(diǎn)小謊。上面我說過“這會(huì)工作得完全一樣”,但這是個(gè)棘手的問題。除了一些函數(shù)的名字改變了,這里還有一些別的不同:在調(diào)用pdisplay之后出現(xiàn)的任何代碼,有可能在實(shí)際的顯示發(fā)生之前被調(diào)用。所以你要么需要使后面的代碼不依賴于顯示的結(jié)束,要么需要從pdisplay返回一個(gè)promise,并且使其他的代碼在promise被裝載之后運(yùn)行。在我的例子中沒有使pdisplay返回一個(gè)promise的一部分原因是,它沒有返回的數(shù)值,因此在我們討論本節(jié)中,promise不能被用來表示成一個(gè)數(shù)值。

不管怎樣,你可以看到如何使你的函數(shù)接受promise,而不只是普通的數(shù)值,可以使你的代碼看起來更干凈更靠近像同步代碼一樣工作。那是promise的一個(gè)美妙之處。在Jedi Toolkit的博客上,從一個(gè)略微不同的觀點(diǎn),有另一個(gè)關(guān)于這個(gè)概念的帖子。

為了流暢的API內(nèi)部使用

某人評(píng)論我的文章說:

我想在解釋promise是做什么的方面,我們寫promise實(shí)現(xiàn)的那些人做得很糟糕。我的觀點(diǎn)是,你作為一個(gè)用戶永遠(yuǎn)都不應(yīng)該被迫與promise用then()交互。then()是promise消費(fèi)庫用來相互之間交互,并且提供流暢的API的一種途徑。你應(yīng)該仍然像通常一樣使用回調(diào)與事件。

他的評(píng)論非常好的契合了前面關(guān)于使用promise代表數(shù)值的一節(jié)。通過使用promise代表數(shù)值,我們能夠創(chuàng)建簡單的像上面看到的API,但這里我們?cè)谟懻撘粋€(gè)鏈接的API。根本上說,這個(gè)評(píng)論者是在告訴我們,要在一個(gè)異步命令鏈的末尾使用回調(diào),以便我們?nèi)匀辉谧鑫覀冞^去習(xí)慣做的(在末尾使用回調(diào)),而無人能說出我們?cè)谑褂胮romise。他想使promise遠(yuǎn)離普通用戶,只在我們自己庫的內(nèi)部使用??匆幌逻@個(gè)查詢數(shù)據(jù)庫,并越來越異步過濾結(jié)果的例子。

Chained .then Calls

 
 
 
  1. database.find()
  2. .then(function(results1) {
  3.     return results1.filter('name', 'Joe');
  4. })
  5. .then(function(results2) {
  6.     return results2.limit(5);
  7. })
  8. .then(function(resultsForReal) {
  9.     // Do stuff with the results
  10. });

不論什么原因,filter和limit其實(shí)是異步的。 可能你覺得它們不應(yīng)該這樣,但是它們就是這樣的。好了,評(píng)論家建議修改 API,保證用戶可以這樣使用:

順暢的API例子

 
 
 
  1. database.find().filter('name', 'Joe').limit(5, function(results){
  2.     // Do stuff with the results
  3. });

這對(duì)我似乎更有意思。如果你能掌控它的運(yùn)行,這是你應(yīng)當(dāng)采取的線路。你可以修改一點(diǎn), 替代普通的回調(diào),仍然返回promise:

返回Promise

 
 
 
  1. var results = database.find().filter('name', 'Joe').limit(5);
  2. results.then(function(realResults){
  3.     // Do stuff with the results
  4. });
  5. // OR use results like in the previous section:
  6. doStuffWith(results);

選擇權(quán)在你。我認(rèn)為老道的開發(fā)者明白返回promise給用戶沒有什么問題,但這確實(shí)是個(gè)見仁見智的問題。無論哪種方式,都比我們需要先串起再調(diào)用的情況好許多。

同步并行的錯(cuò)誤隔離

有一篇相當(dāng)著名的文章叫做You're Missing the Point of Promises,和本文觀點(diǎn)一致。那篇文章中,Domenic Denicola(押頭韻的好名字)指導(dǎo)了部分關(guān)于then函數(shù)的Promises/A規(guī)范。

then(fulfilledHandler, errorHandler, progressHandler)

添加了fulfilledHandler、errorHandler和progressHandler,這三個(gè)處理函數(shù)在promise完成時(shí)被調(diào)用。Promise完成時(shí),調(diào)用fulfilledHandler。Promise失敗時(shí),調(diào)用errorHandler。觸發(fā)postgress事件時(shí),調(diào)用progressHandler。所有參數(shù)都是可選的,并且非函數(shù)類型的值會(huì)被忽略。不僅progressHandler參數(shù)是可選的,而且progress也是完全可選的。Promise的實(shí)現(xiàn)者們不必要在任何時(shí)候調(diào)用progressHandler,如果有postgress事件到來就調(diào)用它。

給出的fulfilledHandler和errorHandler回調(diào)函數(shù)完成時(shí),此函數(shù)應(yīng)當(dāng)返回一個(gè)成功的新promise。這就允許promise操作串起來?;卣{(diào)函數(shù)handler的返回值是返回promise的完成值。如果回調(diào)函數(shù)拋出錯(cuò)誤,那么返回的promise會(huì)被移交到失敗狀態(tài)。

在他的文章中,他在最后一段表明了用途,這是他稱之為的“最重要”的一段。他說:

問題是,promises不是回調(diào)函數(shù)的聚集體。那是一種簡單的功用。Promises是更加深層的東西,具體說就是,它提供了同步和異步函數(shù)的直接對(duì)應(yīng)。

我完全同意這個(gè)觀點(diǎn)。然后他繼續(xù)特別地關(guān)注最后的那個(gè)句子:“如果回調(diào)函數(shù)拋出一個(gè)錯(cuò)誤,返回的promise將會(huì)轉(zhuǎn)為失敗狀態(tài)?!彼P(guān)注這個(gè)句子的原因是jQuery的實(shí)現(xiàn)可能實(shí)現(xiàn)了Promises/A規(guī)范,但沒有這樣做。如果一個(gè)錯(cuò)誤在回調(diào)函數(shù)里拋出,它在promise的實(shí)現(xiàn)里變得不可捕獲。

對(duì)于大多數(shù)人來說這點(diǎn)是非常重要的,盡管我還沒有遇到這種情況,這種情況確實(shí)是個(gè)問題,因?yàn)槲也唤?jīng)常拋出錯(cuò)誤。錯(cuò)誤的promise等價(jià)于一個(gè)錯(cuò)誤或者異常,所以,如果錯(cuò)誤存在,這時(shí)應(yīng)該是失敗而不是拋出一個(gè)錯(cuò)誤。這種方法下我們能夠繼續(xù)使用promise來并行同步操作。我認(rèn)為我們都應(yīng)該 把這個(gè)bug報(bào)告給jQuery。更多的人去報(bào)告這錯(cuò)誤,就更可能快的被修復(fù)。jQuery的promise是最常使用的實(shí)現(xiàn)之一,所以我們應(yīng)該確定他們的做法是正確的。

結(jié)論

啊呀!這肯定是我寫過的最長的帖子了。我原想只是這么一半長的!不管怎樣,promise的重點(diǎn)是它代表一個(gè)操作返回的最終結(jié)果值,但使用它們的原因是使同步操作更好的并行。自從異步編程進(jìn)入此場景,到處都是彈出的回調(diào),以奇怪的方式遮住我們的代碼。Promise是一種改變其的方法。Promise允許我們以同步的方式寫代碼,同時(shí)給予我們代碼的異步執(zhí)行。


網(wǎng)頁名稱:什么是Promises的重點(diǎn)
鏈接URL:http://www.dlmjj.cn/article/coohpcp.html