<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可以表達一連串嵌套的異步操作。 每個Promise實例代表一個異步操作。 ~~~ var p = new Promise(function (resolve) { setTimeout(function () { resolve({}); }, 100); }); p.then(function (data) { }); ~~~ 參數resolve將接受一個函數,該函數用于異步回調時傳遞結果。 然后Promise的實例使用then函數,便可以處理resolve傳遞過來的結果。 then可以鏈式操作,增強Promise的表達能力。每次執行then部署的任務``相當于拋出一個新的Promise實例。 因此可以優雅地表達在異步操作中拋出異步操作。 ~~~ p.then(function (data) { //p返回結果后執行 return new Promise(p1); }).then(function(data){ //p1返回結果后執行 }); ~~~ Promise有一套實現標準和使用方法,具體此處不再詳述。下文用ES代碼實現Promise這個輪子。 # 實現的范圍 Promise對象: * Promise.resolve(value)//接受一個異步結果,返回一個成功的Promise實例。 * Promise.reject(reason)//接受一個異步錯誤,返回一個失敗的Promise實例。 Promise實例: * Promise.prototype.then(onSuccess,onFailure)//接受兩個參數,配置異步成功和失敗時的處理函數,返回一個新的Promise實例。 * Promise.prototype.catch(onFailure)//接受一個參數,配置異步失敗時的處理函數,返回一個新的Promise實例。 # 代碼骨架 ~~~ (function () { "use strict"; //狀態枚舉 var emStatus = { pending: 0, resolved: 1, rejected: 2 }; var Promise = function (task) { this.then = function (onSuccess, onFailure) { }; this.catch = function (onFailure) { }; var status = emStatus.pending,//任務的狀態 boxValue,//任務的結果 chain = { resolve, reject };//拋出的Promise實例的觸發裝置 var resolve = function (value) { }; var reject = function (reason) { }; //給異步(同步)操作注入resolve和reject task(resolve, reject); }; Promise.resolve = function (value) { return new Promise(function (resolve) { resolve(value); }); }; Promise.reject = function (reason) { return new Promise(function (resolve, reject) { reject(reason); }); }; return Promise; })(); ~~~ then和catch所部署的函數的觸發,取決于Promise實例的內部狀態。所以then和catch寫進了Promise實例的構造函數,以引用包含Promise實例內部狀態的環境。 如此一來,Promise實例只能被創建時注入的resolve和reject函數所觸發。這種具有內部封閉性的對象才能稱得上是真正的對象。 Promise實例我設置了三個狀態變量。 * status為任務的狀態,有三個,未開始(pending),成功(resolved)和失敗(rejected)。 * boxValue為任務的結果,成功失敗的結果都會被保存。 * 因為then會拋出一個新的Promise實例,所以需要保存該實例的觸發裝置,使用chain保存resolve和reject觸發裝置。 Promise.resolve/Promise.reject如意義上的拋出一個新的成功/失敗Promise實例。 # 骨架的優化和改進。 catch函數實際上相當于then(null,onFailure)。因此不用每次在構造函數中構造,只需要使用原型鏈的方式訪問。 同一個異步Promise實例的then函數可以被觸發多次,因此chain應該是個數組。 ~~~ (function () { "use strict"; var emStatus = { pending: 0, resolved: 1, rejected: 2 }; var Promise = function (task) { this.then = function (onSuccess, onFailure) { }; var status = emStatus.pending, boxValue, chainArr = []; var resolve = function (value) { }; var reject = function (reason) { }; task(resolve, reject); }; Promise.prototype = { catch: function (onFailure) { return this.then(null, onFailure); } }; Promise.resolve = function (value) { return new Promise(function (resolve) { resolve(value); }); }; Promise.reject = function (reason) { return new Promise(function (resolve, reject) { reject(reason); }); }; return Promise; })(); ~~~ 此時只要實現then,resolve和reject。 # then Promise實例使用then的時候,他可能有三種狀態。仍未觸發回調的pending,已經有結果的resolved和rejected。 ~~~ this.then = function (onSuccess, onFailure) { switch (status) { case emStatus.pending: return new Promise(function (resolve, reject) { var chain = {}; if (onSuccess) { } else { chain.resolve = resolve; } if (onFailure) { } else { chain.reject = reject; } chainArr.push(chain); }); case emStatus.resolved: if (onSuccess) { } else { return Promise.resolve(boxValue); } case emStatus.rejected: if (onFailure) { } else { return Promise.reject(boxValue); } } }; ~~~ ## pending 如果then沒有傳入參數,即沒有部署操作結果的處理函數。那么返回的Promise實例將繼承之前操作的結果。 如果pending狀態時部署了處理函數,那么在未來,將會用該函數對操作返回結果進行處理。被處理后的結果,將是一個resolved的結果。期間發生異常,將被判斷為rejected。 這個處理函數包括操作成功和失敗時的處理函數: ~~~ var result; try { result = on(value); } catch (e) { reject(e); return; } if (result instanceof Promise) { result.then(function (value) { resolve(value); }); } else { resolve(result); } ~~~ 如果處理函數接著拋出一個Promise實例,那么需要等該Promise實例觸發回調后才把處理函數視為返回了結果。 以上就是處理函數的內容,那么我們需要再將其抽象為下一個Promise的觸發裝置。 而且,因為處理函數包括成功和失敗的處理函數,所以可以抽象一個通用的模板。我給他取名nextPromise。 ~~~ var nextPromise = function (on, resolve, reject) { return function (value) { var result; try { result = on(value); } catch (e) { reject(e); return; } if (result instanceof Promise) { result.then(function (value) { resolve(value); }); } else { resolve(result); } }; }; ~~~ 使用該模板,就能生成下一個Promise的觸發裝置。 ~~~ chain.resolve = nextPromise(onSuccess, resolve, reject); ~~~ ## resolved和rejected Promise實例完成狀態的then,情況比較簡單。只要保證返回結果一定是Promise就可以了,我給他取名getPromise。 ~~~ var getPromise = function (on, value) { var result; try { result = on(value); } catch (e) { return Promise.reject(e); } if (result instanceof Promise) { return result; } else { return Promise.resolve(result); } }; ~~~ ## then 所以then的最終代碼是 ~~~ this.then = function (onSuccess, onFailure) { switch (status) { case emStatus.pending: return new Promise(function (resolve, reject) { var chain = {}; if (onSuccess) { chain.resolve = nextPromise(onSuccess, resolve, reject); } else { chain.resolve = resolve; } if (onFailure) { chain.reject = nextPromise(onFailure, resolve, reject); } else { chain.reject = reject; } chainArr.push(chain); }); case emStatus.resolved: if (onSuccess) { return getPromise(onSuccess, boxValue); } else { return Promise.resolve(boxValue); } case emStatus.rejected: if (onFailure) { return getPromise(onFailure, boxValue); } else { return Promise.reject(boxValue); } } }; ~~~ # resolve和reject 一個Promise實例的狀態只會被改變一次,再要改變的話就拋出異常吧。 改變Promise實例的狀態后,就是觸發之前所有使用then拋出的新Promise實例。 ~~~ var resolve = function (value) { if (status === emStatus.pending) { status = emStatus.resolved; boxValue = value; chainArr.forEach(function (chain) { chain.resolve(value); }); } else { throw value; } }; ~~~ 實際上,reject跟resolve做同一樣的事情。 ~~~ var reject = function (reason) { if (status === emStatus.pending) { status = emStatus.rejected; boxValue = reason; chainArr.forEach(function (chain) { chain.reject(reason); }); } else { throw reason; } }; ~~~ # 最終代碼 ~~~ (function () { "use strict"; var emStatus = { pending: 0, resolved: 1, rejected: 2 }; var Promise = function (task) { this.then = function (onSuccess, onFailure) { switch (status) { case emStatus.pending: return new Promise(function (resolve, reject) { var chain = {}; if (onSuccess) { chain.resolve = nextPromise(onSuccess, resolve, reject); } else { chain.resolve = resolve; } if (onFailure) { chain.reject = nextPromise(onFailure, resolve, reject); } else { chain.reject = reject; } chainArr.push(chain); }); case emStatus.resolved: if (onSuccess) { return getPromise(onSuccess, boxValue); } else { return Promise.resolve(boxValue); } case emStatus.rejected: if (onFailure) { return getPromise(onFailure, boxValue); } else { return Promise.reject(boxValue); } } }; var status = emStatus.pending, boxValue, chainArr = []; var resolve = function (value) { if (status === emStatus.pending) { status = emStatus.resolved; boxValue = value; chainArr.forEach(function (chain) { chain.resolve(value); }); } else { throw value; } }; var reject = function (reason) { if (status === emStatus.pending) { status = emStatus.rejected; boxValue = reason; chainArr.forEach(function (chain) { chain.reject(reason); }); } else { throw reason; } }; try { task(resolve, reject); } catch (e) { reject(e); } }; Promise.prototype = { catch: function (onFailure) { return this.then(null, onFailure); } }; Promise.resolve = function (value) { return new Promise(function (resolve) { resolve(value); }); }; Promise.reject = function (reason) { return new Promise(function (resolve, reject) { reject(reason); }); }; var nextPromise = function (on, resolve, reject) { return function (value) { var result; try { result = on(value); } catch (e) { reject(e); return; } if (result instanceof Promise) { result.then(function (value) { resolve(value); }); } else { resolve(result); } }; }; var getPromise = function (on, value) { var result; try { result = on(value); } catch (e) { return Promise.reject(e); } if (result instanceof Promise) { return result; } else { return Promise.resolve(result); } }; return 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>

                              哎呀哎呀视频在线观看