<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                在前面的章節里我們對Promise基本的實例方法?`then`?和?`catch`?的使用方法進行了說明。 這其中,我想大家已經認識了?`.then().catch()`?這種鏈式方法的寫法了,其實在Promise里可以將任意個方法連在一起作為一個方法鏈(method chain)。 promise可以寫成方法鏈的形式 ~~~ aPromise.then(function taskA(value){ // task A }).then(function taskB(vaue){ // task B }).catch(function onRejected(error){ console.log(error); }); ~~~ 如果把在?`then`?中注冊的每個回調函數稱為task的話,那么我們就可以通過Promise方法鏈方式來編寫能以taskA → task B 這種流程進行處理的邏輯了。 Promise方法鏈這種叫法有點長(其實是在日語里有點長,中文還可以 --譯者注),因此后面我們會簡化為?[promise chain](http://liubin.github.io/promises-book/#promise-chain)?這種叫法。 Promise之所以適合編寫異步處理較多的應用,promise chain可以算得上是其中的一個原因吧。 在本小節,我們將主要針對使用?`then`?的promise chain的行為和流程進行學習。 ## 2.4.1\. promise chain 在第一章?[promise chain](http://liubin.github.io/promises-book/#promise-chain)?里我們看到了一個很簡單的 then → catch 的例子,如果我們將方法鏈的長度變得更長的話,那在每個promise對象中注冊的onFulfilled和onRejected將會怎樣執行呢? > promise chain - 即方法鏈越短越好。 在這個例子里我們是為了方便說明才選擇了較長的方法鏈。 我們先來看看下面這樣的promise chain。 promise-then-catch-flow.js ~~~ function taskA() { console.log("Task A"); } function taskB() { console.log("Task B"); } function onRejected(error) { console.log("Catch Error: A or B", error); } function finalTask() { console.log("Final Task"); } var promise = Promise.resolve(); promise .then(taskA) .then(taskB) .catch(onRejected) .then(finalTask); ~~~ 上面代碼中的promise chain的執行流程,如果用一張圖來描述一下的話,像下面的圖那樣。 ![promise-then-catch-flow](https://box.kancloud.cn/2015-07-20_55ac7253d44c0.png) Figure 3\. promise-then-catch-flow.js附圖 在?[上述代碼](http://liubin.github.io/promises-book/#promise-then-catch-flow.js)?中,我們沒有為?`then`?方法指定第二個參數(onRejected),也可以像下面這樣來理解。 `then` 注冊onFulfilled時的回調函數 `catch` 注冊onRejected時的回調函數 再看一下?[上面的流程圖](http://liubin.github.io/promises-book/#promise-then-catch-flow.png)?的話,我們會發現?_Task A_?和?_Task B_?都有指向?_onRejected_?的線出來。 這些線的意思是在?_Task A_?或?_Task B_?的處理中,在下面的情況下就會調用?_onRejected_?方法。 * 發生異常的時候 * 返回了一個Rejected狀態的promise對象 在?[第一章](http://liubin.github.io/promises-book/#how-to-write-promise)?中我們已經看到,Promise中的處理習慣上都會采用?`try-catch`?的風格,當發生異常的時候,會被?`catch`?捕獲并被由在此函數注冊的回調函數進行錯誤處理。 另一種異常處理策略是通過?_返回一個Rejected狀態的promise對象_?來實現的,這種方法不通過使用?`throw`?就能在promise chain中對?`onRejected`?進行調用。 關于這種方法由于和本小節關系不大就不在這里詳述了,大家可以參考一下第4章?[使用reject而不是throw](http://liubin.github.io/promises-book/#not-throw-use-reject)?中的內容。 此外在promise chain中,由于在?_onRejected_?和?_Final Task_?后面沒有?`catch`?處理了,因此在這兩個Task中如果出現異常的話將不會被捕獲,這點需要注意一下。 下面我們再來看一個具體的關于?_Task A_?→?_onRejected_?的例子。 ### Task A產生異常的例子 _Task A_?處理中發生異常的話,會按照TaskA → onRejected → FinalTask 這個流程來進行處理。 ![promise taska rejected flow](https://box.kancloud.cn/2015-07-20_55ac7254c58a4.png) Figure 4\. Task A產生異常時的示意圖 將上面流程寫成代碼的話如下所示。 promise-then-taska-throw.js ~~~ function taskA() { console.log("Task A"); throw new Error("throw Error @ Task A") } function taskB() { console.log("Task B");// 不會被調用 } function onRejected(error) { console.log(error);// => "throw Error @ Task A" } function finalTask() { console.log("Final Task"); } var promise = Promise.resolve(); promise .then(taskA) .then(taskB) .catch(onRejected) .then(finalTask); ~~~ 執行這段代碼我們會發現?_Task B_?是不會被調用的。 > 在本例中我們在taskA中使用了?`throw`?方法故意制造了一個異常。但在實際中想主動進行onRejected調用的時候,應該返回一個Rejected狀態的promise對象。關于這種兩種方法的異同,請參考?[使用reject而不是throw](http://liubin.github.io/promises-book/#not-throw-use-reject)?中的講解。 ## 2.4.2\. promise chain 中如何傳遞參數 前面例子中的Task都是相互獨立的,只是被簡單調用而已。 這時候如果 Task A 想給 Task B 傳遞一個參數該怎么辦呢? 答案非常簡單,那就是在 Task A 中?`return`?的返回值,會在 Task B 執行時傳給它。 我們還是先來看一個具體例子吧。 promise-then-passing-value.js ~~~ function doubleUp(value) { return value * 2; } function increment(value) { return value + 1; } function output(value) { console.log(value);// => (1 + 1) * 2 } var promise = Promise.resolve(1); promise .then(increment) .then(doubleUp) .then(output) .catch(function(error){ // promise chain中出現異常的時候會被調用 console.error(error); }); ~~~ 這段代碼的入口函數是?`Promise.resolve(1);`?,整體的promise chain執行流程如下所示。 1. `Promise.resolve(1);`?傳遞 1 給?`increment`?函數 2. 函數?`increment`?對接收的參數進行 +1 操作并返回(通過`return`) 3. 這時參數變為2,并再次傳給?`doubleUp`?函數 4. 最后在函數?`output`?中打印結果 ![promise-then-passing-value](https://box.kancloud.cn/2015-07-20_55ac7259b3351.png) Figure 5\. promise-then-passing-value.js示意圖 每個方法中?`return`?的值不僅只局限于字符串或者數值類型,也可以是對象或者promise對象等復雜類型。 return的值會由?`Promise.resolve(return的返回值);`?進行相應的包裝處理,因此不管回調函數中會返回一個什么樣的值,最終?`then`?的結果都是返回一個新創建的promise對象。 > 關于這部分內容可以參考?[專欄: 每次調用then都會返回一個新創建的promise對象](http://liubin.github.io/promises-book/#then-return-new-promise)?,那里也對一些常見錯誤進行了介紹。 也就是說,?`Promise#then`?不僅僅是注冊一個回調函數那么簡單,它還會將回調函數的返回值進行變換,創建并返回一個promise對象。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看