萬盛學電腦網

 萬盛學電腦網 >> 腳本專題 >> javascript >> JavaScript異步編程Promise模式的6個特性

JavaScript異步編程Promise模式的6個特性

 Promise說起來是一個非常簡單的概念,即使你沒有機會去使用它,很有可能你也了解過它。Promise是一個非常有價值的構造器,能夠幫助你避免使用鑲套匿名方法,而使用更具有可讀性的方式組裝異步代碼。這裡我們將介紹6個最簡單的特性,希望對大家有幫助

在我們開始正式介紹之前,我們想看看Javascript Promise的樣子:   代碼如下: var p = new Promise(function(resolve, reject) {   resolve("hello world"); });   p.then(function(str) {   alert(str); }); 1. then()返回一個Forked Promise   以下兩段代碼有什麼區別呢?   代碼如下: // Exhibit A var p = new Promise(/*...*/); p.then(func1); p.then(func2);   // Exhibit B var p = new Promise(/*...*/); p.then(func1) .then(func2); 如果你認真以上兩段代碼等同的話,那麼Promises只不過是一個一維的回調函數數組。然而,其實不是這樣的。每一個then()調用都返回一個forked promise。因此,ExhibitA中,如果func1()拋出一個異常,func2()仍舊正常調用。   在ExhibitB中,如果func1()拋出一個錯誤,fun2()將不會被調用,因為第一個調用返回了一個新的promise,這個在func1()中會被拒絕。結果是func2()被跳過。   總結:promises可以被fork成多個路徑,類似復雜的流程圖。   2. Callback應該傳遞結果   當你運行下面代碼的時候什麼會得到警告提示呢?    代碼如下: var p = new Promise(function(resolve, reject) {   resolve("hello world"); });   p.then(function(str) {}) .then(function(str) {   alert(str); }); 第二個then()中的alert沒有顯示任何內容。這是因為回調函數,在promise的上下文中,因為結果的變化並沒有回調函數。promise期望你的回調函數返回同樣的結果或者返回一個替換結果,然後被傳遞到下一個回調函數中。   類似使用adpater來變化結果,如下:    代碼如下: var feetToMetres = function(ft) { return ft*12*0.0254 };   var p = new Promise(/*...*/);   p.then(feetToMetres) .then(function(metres) {   alert(metres); });  3. 只有來自上一層的異常可以被捕捉   這兩段代碼有什麼區別?    代碼如下: // Exhibit A new Promise(function(resolve, reject) {   resolve("hello world"); }) .then(   function(str) {     throw new Error("uh oh");   },   undefined ) .then(   undefined,   function(error) {     alert(error);   } );     // Exhibit B new Promise(function(resolve, reject) {   resolve("hello world"); }) .then(   function(str) {     throw new Error("uh oh");   },   function(error) {     alert(error);   } );   在第一段代碼中,在第一個then()中的異常被拋出,將會被第二個then()捕捉,然後“uh oh”警告將會被觸發。這個遵循只有前一個層次的異常會被捕捉。   在第二段代碼中,回調函數和錯誤回調函數是同一個層次,意味著當異常在回調中拋出,將不會被捕捉。事實上,第二段代碼的錯誤回調將只會在promise為拒絕狀態或者promise本身出錯的情況下拋出   4. 錯誤可以被恢復   在一個錯誤回調函數中,如果你不重新拋出錯誤,promise會假設你已經從錯誤中恢復,並且反轉成為已解決狀態。在下一個例子中,"i'm saved" 將會被顯示,這是因為在第一個then()中的錯誤回調沒有重新拋出異常。   代碼如下: var p = new Promise(function(resolve, reject) {   reject(new Error("pebkac")); });   p.then(   undefined,   function(error) { } ) .then(   function(str) {     alert("I am saved!");   },   function(error) {     alert("Bad computer!");   } ); Promise可以被看作洋蔥上的層次。每一個then()添加另外一個層次到洋蔥上。每一個層次代表了一個被處理的活動。當層次結束,結果被認為已經修復並且為下一個層次做好了准備。   5. Promises可以被暫停   因為你已經准備好了在一個then()方法中執行,並不意味著你不能夠暫停並且提前運行其他。 為了暫停目前的promise,或者讓它等待以便另外一個promise完成,簡單在then()中返回另外一個promise。   代碼如下: var p = new Promise(/*...*/);   p.then(function(str) {   if(!loggedIn) {     return new Promise(/*...*/);   } }) .then(function(str) {   alert("Done."); }) 在前面代碼中,直到新的promise解析後提示才會出現。這是一個方便的方式在已存在的異步代碼路徑中來引入更多地依賴。例如,你可能發現用戶session已經timeout,並且你可能希望在繼續前面的代碼路徑前初始化第二個登陸。   6. Resolved Promises並不會立刻執行   運行下面代碼會得到提示框麼?   代碼如下: function runme() {   var i = 0;     new Promise(function(resolve) {     resolve();   })   .then(function() {     i += 2;   });   alert(i); } 因為promise被立刻解析,然後then()方法被立刻執行,所以你可能會認為會探出提示2。但是promise定義要求所有的調用都被強制異步。因此提示會在被修改前生成。  
copyright © 萬盛學電腦網 all rights reserved