<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 使用 ~~~ 1.需要知道關于promise: 1.1.promise 的 executor(執行器) 里的代碼是同步的 1.2.promise 的回調是 microTask(微任務) 而 setTimeout 的回調是 task(任務/宏任務) 1.3.microTask 早于 task 被執行。 ~~~ * 標記 https://www.ecma-international.org/ecma-262/6.0/#sec-performpromisethen https://www.ecma-international.org/ecma-262/6.0/#sec-returnifabrupt https://www.ecma-international.org/ecma-262/6.0/#sec-promise-executor >[info] ##### 創建一個Promise ~~~ 1.Promis 通過new的形式創建。在構造函數初始化的時候需要傳入一個函數作為參數,這個函數被稱為 '處理器函數 (executor function)' 即'[executor]:可執行函數' 1.1.new Promise的時候,在Promise內部會立即把[executor]函數執行 1.2.同時給'[executor]'函數傳遞兩個值'函數類型':resolve/reject,當異步任務順利完成且返回結果值時,會調用 'resolve' 函數;而當異步任務失敗且返回失敗原因(通常是一個錯誤對象)時,會調用'reject' 函數。 2.Promise 創建的實例內置私有屬性 2.1.'[[PromiseState]]' 實例狀態:pending準備狀態 fulfilled/resolved成功態 rejected失敗態 2.2.'[[PromiseResult]]'實例的值 3.公共屬性方法 Promise.prototype,提供的方法有例如'then','catch','finally' 4.執行then方法時,存放的兩個方法中的某一個方法執行 p.then(onfulfilledCallback,onrejectedCallback) 4.1.狀態成功執行的是:onfulfilledCallback 4.2.狀態失敗執行的是:onrejectedCallback 4.3.并且把[[PromiseResult]]的值傳遞給方法 ~~~ >[danger] ##### 先看一個簡單案例 ~~~ const promise = new Promise(function (resolve, reject) { // 這里用于“兌現”承諾 console.log('開始') resolve(100) // 承諾達成 // reject(new Error('promise rejected')) // 承諾失敗 }) ~~~ * 如圖 ![](https://img.kancloud.cn/13/02/1302ecaeb96c618f6bf6516a25d252bc_524x297.png) >[danger] ##### 案例二 ~~~ // 創建一個Promise對象,p1對象承諾在未來的某一個時刻完成。 let p1 = new Promise((resolve, reject) => { let num = Math.random()*2 setTimeout( ()=> { if(num>1){ console.log(1) resolve(true) // 承諾達成 }else { console.log(2) reject(false) // 承諾失敗 } },1000) }) ~~~ * 如圖 隨機狀態成功,注意這里控制臺看結果的時候顯示 ![](https://img.kancloud.cn/60/19/60197bcfb2d2bc81d2fc2ad64dc6d986_730x372.png) >[danger] ##### Promise的生命周期 ~~~ 1.在[executor]執行resolve/reject都是為了改變promise實例的狀態和值「結果」,一但狀態被改變成 fulfilled/rejected則不能在改為其他的狀態 2.整個'Promise' 的生命周期 有兩個階段個階段 : 2.1.進行中(pending) 進行中狀態因為操作都沒結束也可以理解成未處理(unsettled) 2.2.當操作處理結束后就會變成已處理的狀態(settled) 3.正是因為這兩個階段會出現三種狀態(當然1.2和1.3的狀態只會出現一種) 3.1.pending: 初始狀態,既不是成功,也不是失敗狀態。 -- 進行中(pending)階段發生的 3.2.fulfilled: 意味著操作成功完成。-- 已處理的狀態(settled) 3.3.rejected: 意味著操作失敗。-- 已處理的狀態(settled) 4.內部的[[PromiseState]] 屬性會被設置為"pending" 、 "fulfilled" 或 "rejected",以反映Promise的狀態。該屬性并未在 Promise 對象上被暴露出來,因此你無法以編程方式判斷 Promise 到底處于哪種狀態。 ~~~ * 如圖 ![](https://img.kancloud.cn/b9/97/b9970cdb792e2688a95c08d0f2c06a55_984x133.jpg) >[info] ## Promise 異步 ~~~ 1.承諾是一個同步,他不是靠then 方法來執行了,then方法只是在未來的某一個時刻來 看兌現承諾結果,畢竟結果是一件未來的事情,承諾是此時此刻的,異步產生是在then 調用 ~~~ >[danger] ##### 案例一 ~~~ 1.執行p.then(onfulfilledCallback,onrejectedCallback) 1.1.首先把傳遞進來的onfulfilledCallback和onrejectedCallback存儲起來存儲在一個容器中:因為可以基于 then給其存放好多個回調函數 1.2.其次再去驗證當前實例的狀態,如果實例狀態是pending,則不做任何的處理, 如果已經變為fulfilled/rejected, 則會通知對應的回調函數執行「但是不是立即執行,而是把其放置在EventQueue中的微任務隊列中」 “promise本 身不是異步的,是用來管理異步的,但是then方法是異步的「微任務」” let p = new Promise((resolve, reject) => { console.log(1); resolve('OK'); //=>同步修改其狀態和結果 console.log(2); }); console.log(p); //此時狀態已經修改為成功... p.then(res=>console.log(res)) console.log(13) ~~~ * 如圖 ![](https://img.kancloud.cn/52/b9/52b9de2ee899613992cd3ee9d798a89c_529x301.png) >[danger] ##### 案例二 ~~~ let p = new Promise((resolve, reject) => { console.log(1); setTimeout(() => { resolve('OK'); // + 改變實例的狀態和值「同步」 // + 通知之前基于then存放的onfulfilledCallback執行「異步的微任務:也是把執行方法的事情放置在EventQueue中的微任務隊列中」 console.log(p); console.log(4); }, 1000); //=>存儲了一個異步的宏任務 console.log(2); }); console.log(p); // 此時接受onfulfilledCallback的時候,狀態還是pending,此時只把方法存儲起來 p.then(result => { console.log('成功-->', result); }); console.log(3); ~~~ ![](https://img.kancloud.cn/66/53/6653cb13b1be41bdb2d8e81be9994e52_1128x539.png) >[danger] ##### 案例三 ~~~ const promise = new Promise(function (resolve, reject) { // 我的承諾是現在的承諾 console.log('我承諾我要好好學習js') // ---------------------成功還是失敗是以后的事-------------------------- // 因為是不可逆的要不成功 要不失敗,所以下面的失敗是被注釋因為也不能執行 resolve('我每天學js24個小時') // 承諾達成 {1} // reject(new Error('我每天打游戲24小時沒時間')) // 承諾失敗 }) // ---------------通過then 來兌現這個承諾的結果---------------------- promise.then(function (value) { // 即便沒有異步操作,then 方法中傳入的回調仍然會被放入隊列,等待下一輪執行 console.log('resolved', value) }, function (error) { console.log('rejected', error) }) console.log('end') // 打印結果: 我承諾我要好好學習js end resolved 我每天學js24個小時 ~~~ >[danger] ##### 總結 ~~~ 1.Promise的參數'executor' 函數內部都是同步,resolve/reject 是向外傳遞結果,then 用來接受參數,即使向下面 這樣,內部沒有任何類似settimeout 的異步方法, resolve('OK');也同步執行完了,但想獲取結果需要,通過then 此時then 會等主線程的任務都完成,然后再去EventQueue中的微任務隊列中去除結果 let p = new Promise((resolve, reject) => { console.log(1); resolve('OK'); //=>同步修改其狀態和結果 console.log(2); }) 但當里面是異步函數時候,內部是同步執行,不過此時同步讀取到setTimeout,setTimeout被推入到webapi線程 當1000 毫秒還沒結束,此時打印p是狀態是pendding,當1000ms 后 resolve('OK'); 此時狀態變為成功,但是需要 then 去接受結果 const p = new Promise((resolve, reject) => { setTimeout(()=>{ resolve('OK'); },1000) // reject('NO'); }) console.log(p) ~~~ >[danger] ##### 關于then 方法 * MDN的圖 ![](https://img.kancloud.cn/8a/33/8a33a9e59e8e7b043432e8a3d89619a0_745x277.png) ~~~ 1.當調用then 方法時候'resolve' 或者'reject'觸發產生的異步函數會被添加到任務隊列中并異步執行 2.通過'MDN'提供的圖來看出新建的'Promise是pending狀態','fulfill'之后就會執行調用then的回調函數了,倘若 'reject'了就會調用'catch'來進行異常處理了,并且無論是調用then還是catch都會返回新的promise,這就是為什么 promise可以鏈式調用了。 3.也就像剛才說的'Promise就是獲取異步返回值',因此'Promise'對象'then' 方法可以理解成獲取當初在 '處理器函數 (executor function)'中的異步方法給出的結果,要注意的是: 'then() 函數會返回一個全新的 Promise,和原來的不同' ~~~ * MDN 中給出的案例 ~~~ let myFirstPromise = new Promise(function(resolve, reject){ //當異步代碼執行成功時,我們才會調用resolve(...), 當異步代碼失敗時就會調用reject(...) //在本例中,我們使用setTimeout(...)來模擬異步代碼,實際編碼時可能是XHR請求或是HTML5的一些API方法. setTimeout(function(){ resolve("成功!"); //代碼正常執行! }, 250); }); myFirstPromise.then(function(successMessage){ //successMessage的值是上面調用resolve(...)方法傳入的值. //successMessage參數不一定非要是字符串類型,這里只是舉個例子 console.log("Yay! " + successMessage); }); ~~~ >[danger] ##### 總結 ~~~ 1.執行then方法會返回一些全新的promise實例 1.1.方法執行不報錯,如果方法中返回一個全新的Promise實例,則全新的Promise實例的成功和失敗決定 下一個成功和失敗,如果不是返回promise則 [[PromiseState]]:fulfiled [[PromiseResult]]:返回值 1.2.如果方法執行報錯:則 [[PromiseState]]:rejected [[PromiseResult]]:報錯原因 ~~~ ~~~ // 其實相當于第一then 返回值為 Promise.resolve(undefined) const p = new Promise((resolve,reject)=>{ resolve(1) }).then(res=>{ console.log(res) // 1 }).then(res=>{ console.log(res) // undefined }) //-------------- const p = new Promise((resolve,reject)=>{ resolve(1) }).then(res=>{ console.log(res) // 1 return Promise.resolve(2) }).then(res=>{ console.log(res)}) // 2 ~~~ >[danger] ##### 循環Promise 數組 1.[參考mdn](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve) ~~~ /** * Runs promises from array of functions that can return promises * in chained manner * * @param {array} arr - promise arr * @return {Object} promise object */ function runPromiseInSequence(arr, input) { return arr.reduce( // Promise.resolve(input).then(currentFunction) (promiseChain, currentFunction) => promiseChain.then(currentFunction), Promise.resolve(input) ); } // promise function 1 function p1(a) { return new Promise((resolve, reject) => { resolve(a * 5); }); } // promise function 2 function p2(a) { return new Promise((resolve, reject) => { resolve(a * 2); }); } // function 3 - will be wrapped in a resolved promise by .then() function f3(a) { return a * 3; } // promise function 4 function p4(a) { return new Promise((resolve, reject) => { resolve(a * 4); }); } const promiseArr = [p1, p2, f3, p4]; runPromiseInSequence(promiseArr, 10) .then(console.log); // 1200 ~~~
                  <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>

                              哎呀哎呀视频在线观看