<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國際加速解決方案。 廣告
                [TOC] >[success] # Promise 更多用法 ~~~ ~~~ >[info] ## 創建Promise 對象 ~~~ 1. 創建Promise 對象的有兩大類別,第一類別就是上一個章節有使用的new 的形式創建可以理解成 '創建未完成的Promise',另一種就是下面章節說的'創建已處理的Promise' ~~~ >[danger] ##### 創建未完成的Promise ~~~ 1.new Promise(executor) -- 參數為'處理器函數 (executor function)' ~~~ * 簡單案例 更多詳細看上一個章節 ~~~ let p1 = new Promise((resolve, reject) => { setTimeout( ()=> { resolve(2) console.log(1) },1000) }) // 使用 p1.then((parmas)=>{ console.log(parmas) }) // 打印結果 1 2 ~~~ >[danger] ##### 創建已處理的Promsie(一) -- resolve ~~~ 1.Promise.resolve()方法接收一個參數,并會返回一個處于已完成狀態的 Promise ,參數有三種形式 1.1.第一種參數形式Promise.resolve(value); -- 普通value參數 1.2.第二種參數形式Promise.resolve(promise); -- promise 對象作為參數 1.3第三種參數形式.Promise.resolve(thenable); -- 擁有then方法并且接受res和rej兩個參數的普通對象就可理解為 'thenable'類型 2.由于該Promise永遠不存在拒絕狀態,因而該Promise的拒絕處理程序永遠不會被調用 ~~~ * 等同的寫法 ~~~ Promise.resolve('foo') .then(function (value) { console.log(value) }) // 等同 new Promise(function (resolve, reject) { resolve('foo') }) ~~~ * 第一種參數 --- value ~~~ const p = Promise.resolve(1) p.then((status)=>{ console.log(status) }) // 打印結果: 1 ~~~ * 第二種參數 -- Promise ~~~ 1.直接返回參數promise這promise 對象,至于這個promise是返回成功還是失敗都取決于參數這個promise的結果 ~~~ ~~~ let p1 = new Promise(function (res,rej) { let num = Math.random()*2 setTimeout(function () { if(num>1){ console.log(1) res(true) }else { console.log(2) rej(false) } },1000) }) const p2 = Promise.resolve(p1) // 此時P2 成功還是失敗狀態完全取決于p1,雖然P2 調用了resolve 也要看 p1實際結果情況 p2.then((status)=>{ console.log(status) }).catch((err)=>{ console.log(err) }) ~~~ * 第三種參數 -- 非Promise 的Thenable對象 ~~~ 1.thenable 對象和Promise之間都有then()方法之一相似之處,當作為參數的時候會將thenanle對象轉化成一個 已完成的Promise對象,注意此時then 會自動加入兩個回調函數參數 ~~~ ~~~ let thenable = { // 會自動加入兩個回調函數參數 then:function (res,rej) { res(42) } } let p1 = Promise.resolve(thenable) p1.then(function (v) { console.log(v) }) ~~~ >[danger] ##### 創建已處理的Promsie(二) -- reject ~~~ 1.Promise.reject()方法接收一個參數,并會返回一個處于已拒絕狀態的 Promise 其余的和 resolve 是一樣的 ~~~ >[info] ## Promise 執行器錯誤和全局的拒絕處理 >[danger] ##### 處理器函數 (executor function)錯誤 ~~~ 1.當創建的Promise 對象中的'處理器函數 (executor function)'內部拋出一個錯誤則'promise'的拒絕處理程序就會 被 調用 2.下面的案例JSON.parse('err') 這個用法明顯錯誤,但會在catch 階段執行也就是'rejected'意味著操作失敗 ~~~ ~~~ let p = new Promise(function (res,rej) { JSON.parse('err') }) p.then((status)=>{ console.log(status) }).catch((err)=>{ console.log('err',err) }) ~~~ * 上面的代碼等同于 ~~~ let p = new Promise(function (res,rej) { try{ JSON.parse('err') }catch (e) { rej(e) } }) p.then((status)=>{ console.log(status) }).catch((err)=>{ console.log('err',err) }) ~~~ >[danger] ##### 全局的Promise 拒絕處理 ~~~ 1.當 Promise 被拒絕時,會有兩個事件之一被派發到全局作用域瀏覽器環境這里指的是'window' 1.1.'rejectionhandled'當 Promise 被'拒絕'、并且在'reject'函數處理該 'rejection' 之后會派發此事件。 1.2.'unhandledrejection'當 Promise 被'拒絕',但沒有提供 'reject' 函數來處理該 'rejection' 時,會派發此事件。 2.這兩個事件event分別有三個屬性 2.1 event.type -- 事件名 2.2.event.promise -- 被拒絕的Promise 對象 2.3.event.reason -- 來自Promise 拒絕值 ~~~ * 這是一個rejected--操作失敗的已處理的狀態(settled),使用'unhandledrejection' 來做監聽 ~~~ window.addEventListener('unhandledrejection', event => { console.log(event.reason); // 打印"Hello, Fundebug!" console.log(event.type); // 'unhandledrejection' console.log(event.promise); // promise 對象 }); var r = foo(); r.then((params)=>{ console.log(params) }) ~~~ * rejectionhandled 事件錯誤沒有立刻處理而是稍后處理就會觸發 ~~~ window.addEventListener('rejectionhandled', event => { console.log('rejection handled'); // 1秒后打印"rejection handled" }); function foo() { return Promise.reject('Hello, Fundebug!'); } var r = foo(); setTimeout(() => { r.catch(e =>{}); }, 1000); ~~~ >[danger] ##### 書中給的一個簡單的未處理拒絕跟蹤器案例 ~~~ let possiblyUnhandledRejections = new Map(); // 當一個拒絕未被處理,將其添加到 map window.onunhandledrejection = function(event) { possiblyUnhandledRejections.set(event.promise, event.reason); }; // 如果是因為延遲才處理的話可以剔除 window.onrejectionhandled = function(event) { possiblyUnhandledRejections.delete(event.promise); }; setInterval(function() { possiblyUnhandledRejections.forEach(function(reason, promise) { console.log(reason.message ? reason.message : reason); // 做點事來處理這些拒絕 handleRejection(promise, reason); }); possiblyUnhandledRejections.clear(); }, 60000); ~~~ >[info] ## 鏈式調用的 -- then ~~~ 1.then 方法返回一個 Promise 對象,其允許方法鏈。 2.當一個值只是從一個 then 內部返回時,它將等價地返回 Promise.resolve(<由被調用的處理程序返回的值>)。 3.也可以返回是一個Promise 對象 ~~~ >[danger] ##### 通過鏈式調用來理解Promise如何解決了地獄回調 ~~~ 1.首先promise如果沒有采用鏈式寫法 其實還是和以前使用地獄回調是一個問題 ~~~ ~~~ function ajax (url) { return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.responseType = 'json' xhr.onload = function () { if (this.status === 200) { resolve(this.response) } else { reject(new Error(this.statusText)) } } xhr.send() }) } // 嵌套使用 Promise 是最常見的誤區 // ajax('/person').then(function (urls) { // ajax(urls.users).then(function (users) { // ajax(urls.users).then(function (users) { // ajax(urls.users).then(function (users) { // ajax(urls.users).then(function (users) { // }) // }) // }) // }) // }) ~~~ * 正確使用 ~~~ function ajax (url) { return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.responseType = 'json' xhr.onload = function () { if (this.status === 200) { resolve(this.response) } else { reject(new Error(this.statusText)) } } xhr.send() }) } ajax('/api/users.json') .then(function (value) { console.log(1111) return ajax('/api/urls.json') }) // => Promise .then(function (value) { console.log(2222) console.log(value) return ajax('/api/urls.json') }) // => Promise .then(function (value) { console.log(3333) return ajax('/api/urls.json') }) // => Promise .then(function (value) { console.log(4444) return 'foo' }) // => Promise .then(function (value) { console.log(5555) console.log(value) }) ~~~ >[danger] ##### 案例 ~~~ 1.執行器傳入的value 值為1,當p2 執行完返回的vaule + 1也就是2,這個值隨后傳給了下一個then,此時相當于 Promise.resolve(<由被調用的處理程序返回的值>),又產生新的異步回調隊列,因此下面P2.then 先打印出1,這個 新的異步回調隊列在在執行 因此最后才打印'2' ~~~ ~~~ var p2 = new Promise(function(resolve, reject) { resolve(1); }); p2.then(function(value) { console.log(value); // 1 return value + 1; }).then(function(value) { console.log(value + '我接收的是上一個promise 的返回值'); }); p2.then(function(value) { console.log(value); // 1 }); // 打印結果 1 1 2我接收的是上一個promise 的返回值 ~~~ >[info] ## 鏈式調用的 -- catch ~~~ 1.和then一樣不過是失敗的時候才觸發 2. catch 返回的也是一個promise 3. catch 是捕獲最近 `reject` 狀態 ~~~ * 如果Promise 異常卻沒有抓異常執行代碼后會有報錯 ![](https://img.kancloud.cn/8c/d4/8cd48c7f49876d9fc8c565d88591e50e_416x44.png) ~~~ const promise = new Promise((resolve, reject) => { reject('failure') }) promise.then((res) => { console.log('成功的回調:', res) }) ~~~ * **catch** 返回的也是一個promise ~~~ const promise = new Promise((resolve, reject) => { reject("error: aaaaa") }) // 1.catch方法也會返回一個新的Promise promise.catch(err => { console.log("catch回調:", err) return "bbbbb" }).then(res => { console.log("then第一個回調:", res) return "ccccc" }).then(res => { console.log("then第二個回調:", res) }) ~~~ 執行結果 ![](https://img.kancloud.cn/5d/5d/5d5de0ffb243409b2beb676be66b0757_373x63.png) * catch 是捕獲最近 `reject` 狀態 ![](https://img.kancloud.cn/e2/df/e2dff913679ddb8c4cee4455bd35a489_907x423.png) ~~~ const promise = new Promise((resolve, reject) => { reject('error: aaaaa') }) promise .then((res) => { console.log('then第一次回調:', res) }) .then((res) => { console.log('then第二次回調:', res) throw new Error('第三個Promise的異常error') }) .then((res) => { console.log('then第三次回調:', res) }) .catch((err) => { console.log('catch回調被執行:', err) }) ~~~ 執行結果 ![](https://img.kancloud.cn/4a/cb/4acb43ebd2450ccd3b452d49d51ea41b_235x30.png) * 通過**throw new Error** 進入catch ~~~ const promise = new Promise((resolve, reject) => { resolve('aaaaaa') }) promise .then((res) => { console.log('then第一次回調:', res) throw new Error('第二個Promise的異常error') }) .then((res) => { console.log('then第二次回調:', res) throw new Error('第三個Promise的異常error') }) .then((res) => { console.log('then第三次回調:', res) }) .catch((err) => { console.log('catch回調被執行:', err) }) ~~~ 執行結果 ![](https://img.kancloud.cn/44/ad/44ad2a7e46c7cb7f174a468b679b6dfc_335x64.png) >[info] ## finally * 比較簡單使用了mdn 上的解答 ~~~ 1.方法返回一個Promise。在promise結束時,無論結果是fulfilled或者是rejected,都會執行指定的回調函數。這為在 Promise是否成功完成后都需要執行的代碼提供了一種方式。 2.這避免了同樣的語句需要在then()和catch()中各寫一次的情況。 ~~~ ~~~ p.finally(onFinally); p.finally(function() { // 返回狀態為(resolved 或 rejected) }); ~~~ >[info] ## Promise -- all ~~~ 1.Promise.all() 方法只接受一個參數并返回Promise。這個參數需要是一個'可迭代對象',結果導向分兩種 1.1. 如果可迭代對象中的'Promise'全部成功,那么Promise.all()會等這些可迭代對象都完成后才會返回 1.2.如果可迭代對象中的'Promise' 對象只要有一個拒絕那么Promise.all()沒有等所有的Promise都返回就 會直接返回這個立刻被拒絕的 簡單的解釋:'Promise.all 等待所有都完成(或第一個失敗)' 2.如果如果傳入的可迭代對象是空的,就是同步,Promise.all() 就是同步觸發 ~~~ >[danger] ##### 解釋第一條 * 全部成功狀態 ~~~ var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)]; var p = Promise.all(resolvedPromisesArray); p.then((value)=>{ console.log(value) }) 打印結果: [33, 34] // 返回的是可迭代對象中Promise 所有成功返回值的數組形式 ~~~ * 有一個失敗狀態 ~~~ var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44),Promise.resolve(55)]; var p = Promise.all(mixedPromisesArray); p.then((value)=>{ console.log(value) }).catch((err)=>{ console.log(err,'失敗') }) 打印結果: 44 "失敗" ~~~ >[danger] ##### 解釋第二條 ~~~ var resolvedPromisesArray = [Promise.resolve(33),Promise.resolve(32)]; var unPromisesArray = [1,2]; var emptyPromises = [] // 可迭代對象中的參數都是Promise 對象 var p1 = Promise.all(resolvedPromisesArray); // 可迭代對象 中的參數都是非Promise 對象 var p2 = Promise.all(unPromisesArray); // 可迭代對象為空 var p3 = Promise.all(emptyPromises) // 立即打印p1 和 p2 console.log(p1); console.log(p2); console.log(p3); // 使用setTimeout,我們可以在堆棧為空后執行代碼 setTimeout(function(){ console.log(p1); console.log(p2); console.log(p3); }); ~~~ * 執行結果如圖 ![](https://img.kancloud.cn/eb/00/eb007c638fc37702484040e47291dbf5_620x185.png) >[info] ## race ~~~ 1.Promise.race(iterable) 方法返回一個 promise,一旦迭代器中的某個promise解決或拒絕,返回的 promise就會解決或拒絕 2.Promise.race(iterable) 中迭代對象里面的Promise對象是競爭關系,那個快就先返回最快的那個成功或者失敗 ~~~ >[danger] ##### 案例 ~~~js var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 500, "one"); }); var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, "two"); }); Promise.race([p1, p2]).then(function(value) { console.log(value); // "two" // 兩個都完成,但 p2 更快 }); ~~~ >[danger] ##### 圖片的加載 ~~~ 1.有時候圖片加載想做一個計時,當超過某個特定時間的時候,就返回告訴加載超時就可以使用race ~~~ ~~~ //請求某個圖片資源 function requestImg(){ var p = new Promise(function(resolve, reject){ var img = new Image(); img.onload = function(){ resolve(img); } img.src = 'http://www.baidu.com/img/flexible/logo/pc/result.png'; }); return p; } //延時函數,用于給請求計時 function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('圖片請求超時'); }, 5000); }); return p; } Promise.race([requestImg(), timeout()]) .then(function(results){ console.log(results); }) .catch(function(reason){ console.log(reason); }); ~~~ >[info] ## 總結 [總結圖片來源](https://kaiwu.lagou.com/course/courseInfo.htm?courseId=601#/detail/pc?id=6187) ![](https://img.kancloud.cn/77/9b/779befa7d802311a7b7463cece0fc9bf_517x177.png)
                  <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>

                              哎呀哎呀视频在线观看