<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] # async 配合 await [先看這個章節鏈接](http://www.hmoore.net/cyyspring/more/2241086) [mdn好文章必讀收獲滿滿](https://developer.mozilla.org/zh-CN/docs/learn/JavaScript/%E5%BC%82%E6%AD%A5/Async_await) ~~~ 1.雖然es6 提供了Promise 作為異步處理解決了地獄回調的問題,但是在書寫一直鏈式使用then 確實也是和正常邏輯代碼書樣子還是有一定差別的,在es8 async 配合 await可以解決相對應 的問題 2.或者使用co 函數庫 ,但是現在async 配合 await 可以完全替代他了 3.async 函數 func 最后返回的結果直接是 Promise 對象 4.await 操作符用于等待一個Promise 對象,mdn 的介紹: await 表達式會暫停當前 async function 的執行,等待 Promise 處理完成。若 Promise 正常處理(fulfilled),其回調的resolve函數參數作為 await 表達式的值,繼續執行 async function。 若 Promise 處理異常(rejected),await 表達式會把 Promise 的異常原因拋出。 另外,如果 await 操作符后的表達式的值不是一個 Promise,則返回該值本身 ~~~ >[info] ## 使用 ~~~ 1.async:函數修飾符 控制函數返回promise實例 1.1.函數內部執行報錯,則返回失敗的promise實例,失敗的原因 1.2.自己返回一個promise,以自己返回的為主 1.3.如果函數內部做了異常捕獲,則還是成功態 2.使用async的主要目的:是為了在函數內部使用await 3.await:后面應該放置一個promise實例我們書寫的不是,瀏覽器也會把其變為promise實例 3.1.await是異步的微任務 3.2.如果我們的異步函數的返回值是一個對象并且實現了thenable,那么會由對象的 then方法來決定 3.3.await會等到Promise的狀態變成fulfilled狀態,之后繼續執行異步函數 ~~~ >[danger] ##### 案例 ~~~ async function fn() { return 10; // 其實相當于 return Promise.resolve(10) } console.log(fn()); ~~~ * 如圖 ![](https://img.kancloud.cn/7d/71/7d71d339d433b5630938e6b5a82d5fb1_412x181.png) >[danger] ##### 案例二 解釋1.3 ~~~ async function fn() { try { console.log(a) } catch (e) {} } console.log(fn()) ~~~ * 如圖 ![](https://img.kancloud.cn/e6/35/e635c1bd2a81f2bbe6652781fb7a2505_415x210.png) * 雖然返回異常但也是成功 ![](https://img.kancloud.cn/1f/72/1f72da363068845025011c15a13932fc_916x251.png) >[danger] ##### 案例三 解釋await 1. await后面是一個普通的值,那么會直接返回這個值 2. await后面是一個thenable的對象,那么會根據對象的then方法調用來決定后續的值 3. await后面的表達式,返回的Promise是reject的狀態,那么會將這個reject結果直接作為函數的Promise的reject值 ~~~ async function func() { // await 1; //-> await Promise.resolve(1); let result1 = await api(1000); console.log(result1); let result2 = await api(3000); console.log(result2); } func(); ~~~ >[danger] ##### 異步函數有返回值時,和普通函數會有區別 1. 異步函數也可以有返回值,但是異步函數的返回值相當于被包裹到Promise.resolve中 2. 果我們的異步函數的返回值是Promise,狀態由會由Promise決定 3. 如果我們的異步函數的返回值是一個對象并且實現了thenable,那么會由對象的then方法來決定 ~~~ async function foo2() { // 1.返回一個普通的值 // -> Promise.resolve( ["abc", "cba", "nba"]) return ["abc", "cba", "nba"] // 2.返回一個Promise // return new Promise((resolve, reject) => { // setTimeout(() => { // resolve("aaa") // }, 3000) // }) // 3.返回一個thenable對象 // return { // then: function(resolve, reject) { // resolve("bbb") // } // } } ~~~ ~~~ foo2().then(res => { console.log("res:", res) // 情況1 ["abc", "cba", "nba"] 情況2 aaa 情況三bbb }) ~~~ >[danger] ##### 異步異常 1. 調用后通過catch 接受異常 ~~~ async function foo() { throw new Error("1") // return new Promise((resolve, reject) => { // reject("err rejected")1 // }) return 123 } // promise -> pending -> fulfilled/rejected foo().then(res => { console.log("res:", res) }).catch(err => { console.log(" err:", err) console.log("繼續執行其他的邏輯代碼") }) ~~~ 2. await 接受異步如果是異常 ~~~ function requestData(url) { return new Promise((resolve, reject) => { setTimeout(() => { // reject("error message") }, 2000) }) } async function getData() { const res1 = await requestData('1') console.log('res1:', res1) const res2 = await requestData(res1 + '2') console.log('res2:', res2) } getData().catch((err) => { console.log('err:', err) }) ~~~ >[info] ## Promise 和 async 等同寫法 ~~~ 1.第一種sequential 是所有總和時間,后續四種都是以最長時間為準 ~~~ ~~~ var resolveAfter2Seconds = function resolveAfter2Seconds() { console.log('starting slow promise') return new Promise((resolve) => { setTimeout(function () { resolve('slow') console.log('slow promise is done') }, 5000) }) } var resolveAfter1Second = function resolveAfter1Second() { console.log('starting fast promise') return new Promise((resolve) => { setTimeout(function () { resolve('fast') console.log('fast promise is done') }, 1000) }) } // sequential:相繼的 /[s??kwen?l]/ var sequential = async function sequential() { console.time('3') console.log('==SEQUENTIAL START==') const slow = await resolveAfter2Seconds() console.log(slow) const fast = await resolveAfter1Second() console.log(fast) console.timeEnd('3') } // concurrent:同時發生的 /[k?n?k?r?nt]/ var concurrent = async function concurrent() { console.time('1') console.log('==CONCURRENT START with await==') const slow = resolveAfter2Seconds() const fast = resolveAfter1Second() console.log(await slow) console.log(await fast) console.timeEnd('1') } var concurrentPromise = function concurrentPromise() { console.log('==CONCURRENT START with Promise.all==') return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then( (messages) => { console.log(messages[0]) console.log(messages[1]) } ) } // parallel:平行的 /[?p?r?lel]/ var parallel = async function parallel() { console.time('2') console.log('==PARALLEL with await Promise.all==') await Promise.all([ (async () => { let result = await resolveAfter2Seconds() console.log(result) })(), (async () => { let result = await resolveAfter1Second() console.log(result) })(), ]) console.timeEnd('2') } var parallelPromise = function parallelPromise() { console.log('==PARALLEL with Promise.then==') resolveAfter2Seconds().then((message) => console.log(message)) resolveAfter1Second().then((message) => console.log(message)) } sequential() // 6S+ // concurrent() // 5S+ // concurrentPromise() // 5S+ // parallel() // 5S+ // parallelPromise() // 5S+ ~~~ >[info] ## 了解生成器函數 ~~~ 1.next 執行下一步,yield會返回一個迭代器對象,生成器函數可以用throw 接受拋出的異常 ~~~ ~~~ // 生成器函數回顧 function * foo () { console.log('start') try { const res = yield 'foo' console.log(res) } catch (e) { console.log(e) } } const generator = foo() const result = generator.next() console.log(result) // generator.next('bar') generator.throw(new Error('Generator error')) // 打印結果 start { value: 'foo', done: false } Error: Generator error ~~~ >[danger] ##### Generator 配合 Promise 的異步方案 ~~~ 1.現在定義main 方法中的異步寫起來已經和同步方法的感覺一樣 可以依次執行 ,也不用鏈式使用, 配合封裝co方法 ~~~ ~~~ // Generator 配合 Promise 的異步方案 function ajax (url) { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.responseType = 'json' xhr.onload = () => { if (xhr.status === 200) { resolve(xhr.response) } else { reject(new Error(xhr.statusText)) } } xhr.send() }) } function * main () { try { const users = yield ajax('/api/users.json') console.log(users) const posts = yield ajax('/api/posts.json') console.log(posts) const urls = yield ajax('/api/urls11.json') console.log(urls) } catch (e) { console.log(e) } } function co (generator) { const g = generator() // 通過生成器返回的迭代器對象的格式配合遞歸結合Promise 實現 function handleResult (result) { if (result.done) return // 生成器函數結束 result.value.then(data => { handleResult(g.next(data)) }, error => { g.throw(error) }) } handleResult(g.next()) } co(main) ~~~ >[info] ## 封裝遞歸的方法過于麻煩 使用async 和awit 配合 ~~~ const pr = new Promise((resolve, reject) => { resolve(1) }) async function te() { const a = await pr console.log(a) console.log(2) } te() console.log(3) // 打印結果: 3 1 2 ~~~ * 如果想讓上面打印 1 2 3的順序 ~~~ const pr = new Promise((resolve, reject) => { resolve(1) }) async function te() { const a = await pr console.log(a) console.log(2) } te().then(() => { console.log(3) }) ~~~ >[danger] ##### Async / Await 語法糖 ~~~ 1.Async / Await 返回的是一個promise 因此可以通過then 繼續調用 ~~~ ~~~ // Async / Await 語法糖 function ajax (url) { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.responseType = 'json' xhr.onload = () => { if (xhr.status === 200) { resolve(xhr.response) } else { reject(new Error(xhr.statusText)) } } xhr.send() }) } // function co (generator) { // const g = generator() // function handleResult (result) { // if (result.done) return // 生成器函數結束 // result.value.then(data => { // handleResult(g.next(data)) // }, error => { // g.throw(error) // }) // } // handleResult(g.next()) // } async function main () { try { const users = await ajax('/api/users.json') console.log(users) const posts = await ajax('/api/posts.json') console.log(posts) const urls = await ajax('/api/urls.json') console.log(urls) } catch (e) { console.log(e) } } // co(main) const promise = main() promise.then(() => { console.log('all completed') }) ~~~
                  <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>

                              哎呀哎呀视频在线观看