久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

深入探討JavaScript中的async函數

深入探討JavaScript中的async函數

前端(vue)入門到精通課程:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調試工具:點擊使用

async函數

async函數的返回值為 promise 對象,promise對象的結果由async函數執行的返回值決定。async函數能使得異步操作變得更加方便,簡而言之就是 Generator 的語法糖。

定義async函數,特點是即便函數內部返回結果不是promise對象,調用函數其最后的返回結果依然是promise對象,代碼如下:

如果返回的結果不是 Promise 對象的情況下:

<script>     async function fn(){         // 返回的結果是字符串         // return '123'         // // 返回的結果是undefined         // return;         // 返回的結果是拋出一個異常         throw new 'error'     }     const result = fn()     console.log(result); </script>
登錄后復制

深入探討JavaScript中的async函數

如果返回的結果是 Promise 對象時,我們正常使用 then 方法即可,如下:

<script>     async function fn(){         return new Promise((resolve,reject)=>{             // resolve('成功的數據')             reject('失敗的數據')         })     }     const result = fn()     // 調用 then 方法     result.then((value)=>{         console.log(value);     },(reason)=>{         console.log(reason); // 打印失敗的數據     }) </script>
登錄后復制

await 表達式

通過上文的對 async 介紹,感覺其功能有點雞肋,其實恰恰不是,而是 async 需要搭配 await 一起使用才能達到語法糖的效果。

await的特點

await必須寫在 async 函數中

await右側的表達式一般為 promise 對象

await返回的是 promise 成功的值

await的 promise 失敗了,就會拋出異常,需要通過 try…catch捕獲處理

說白了:await就相當于 then 方法的第一個回調函數,只返回成功的值,失敗的值需要 try…catch來捕獲。

async函數內部拋出錯誤,會導致返回的 Promise 對象變為reject狀態。拋出的錯誤對象會被catch方法回調函數接收到。

<script>     const p = new Promise((resolve,reject)=>{         // resolve('用戶數據')         reject('用戶加載數據失敗了')     })     async function fn(){         // 為防止promise是失敗的狀態,加上try...catch進行異常捕獲         try {             // await 返回的結果就是 promise 返回成功的值             let result = await p             console.log(result);         } catch (error) {             console.log(error);//因為是失敗的狀態,所以打印:用戶加載數據失敗了         }     }     fn() </script>
登錄后復制

總結

(1)await命令后面的Promise對象,運行結果可能是rejected,所以最好把await命令放在try…catch代碼塊中。

(2)如果有多個await命令后面的異步操作,如果不存在繼發關系,最好讓它們同時觸發。

比如:await Promise.all([a(), b()]),這里簡單提一下

(3)await命令只能用在async函數之中,如果用在普通函數,就會報錯。

(4)(理解一下async的運行原理) async 函數可以保留運行堆棧,普通函數內部運行一個異步任務時,如果異步任務運行結束普通函數可能早就運行完了,異步任務的上下文環境已經消失了,如果異步任務報錯,錯誤堆棧將不包括普通函數;而async函數內部的異步任務運行時,async函數是暫停執行的,所以一旦async函數內部的異步任務運行報錯,錯誤堆棧將包括async函數。

async使用形式

// 函數聲明 async function foo() {}   // 函數表達式 const foo = async function () {};   // 對象的方法 let obj = { async foo() {} }; obj.foo().then(...)   // Class 的方法 class Storage {   constructor() {     this.cachePromise = caches.open('avatars');   }     async getAvatar(name) {     const cache = await this.cachePromise;     return cache.match(`/avatars/${name}.jpg`);   } }   const storage = new Storage(); storage.getAvatar('jake').then(…);   // 箭頭函數 const foo = async () => {};
登錄后復制

async讀取文件

和之前講解的 promise 讀取文件內容 一樣,我們也可以使用async進行文件的讀取,代碼如下:

// 1.引入 fs 模塊 const fs = require('fs')   // 2.讀取文件 function index(){     return new Promise((resolve,reject)=>{         fs.readFile('./index.md',(err,data)=>{             // 如果失敗             if(err) reject(err)             // 如果成功             resolve(data)         })     }) } function index1(){     return new Promise((resolve,reject)=>{         fs.readFile('./index1.md',(err,data)=>{             // 如果失敗             if(err) reject(err)             // 如果成功             resolve(data)         })     }) } function index2(){     return new Promise((resolve,reject)=>{         fs.readFile('./index2.md',(err,data)=>{             // 如果失敗             if(err) reject(err)             // 如果成功             resolve(data)         })     }) }   // 3.聲明一個 async 函數 async function fn(){     let i = await index()     let i1 = await index1()     let i2 = await index2()     console.log(i.toString());     console.log(i1.toString());     console.log(i2.toString()); } fn()
登錄后復制

深入探討JavaScript中的async函數

async發送AJAX請求

和之前講解 promise發送ajax請求 一樣,我們也可以使用async進行發送ajax請求,代碼如下:

<script>     // 發送 AJAX請求,返回的結果是 Promise 對象     function sendAjax(url){         return new Promise((resolve,reject)=>{             // 創建對象             const x = new XMLHttpRequest()               // 初始化             x.open('GET',url)               // 發送             x.send()               // 事件綁定             x.onreadystatechange = function(){                 if(x.readyState === 4){                     if(x.status >= 200 && x.status < 300){                         // 如果響應成功                         resolve(x.response)                         // 如果響應失敗                         reject(x.status)                     }                 }             }         })     }              // promise then 方法測試     // const result = sendAjax("https://ai.baidu.com/").then(value=>{     //     console.log(value);     // },reason=>{})     // async 與 await 測試     async function fn(){         // 發送 AJAX 請求         let result = await sendAjax("https://ai.baidu.com/")         console.log(result);     }     fn() </script>
登錄后復制

深入探討JavaScript中的async函數

與生成器(Generator)相比

我們發現 async與await之間的關系 和 Generator與yield之間的關系十分類似,不熟悉Generator的朋友可以看一下我之前的文章:生成器講解 ;一比較就發現: async函數就是將 Generator 函數的星號(*)替換成async,將yield替換成await。代碼比較如下:

<script>     // Generator 函數     function * person() {         console.log('hello world');         yield '第一分隔線'               console.log('hello world 1');         yield '第二分隔線'              console.log('hello world 2');         yield '第三分隔線'     }     let iterator = person()     // console.log(iterator); 打印的就是一個迭代器對象,里面有一個 next() 方法,我們借助next方法讓它運行     iterator.next()     iterator.next()     iterator.next()       // async函數     const person1 = async function (){         console.log('hello world');         await '第一分隔線'               console.log('hello world 1');         await '第二分隔線'              console.log('hello world 2');         await '第三分隔線'     }     person1() </script>
登錄后復制

深入探討JavaScript中的async函數

async函數的實現原理就是將 Generator 函數和自動執行器包裝在一個函數里。

<script>     async function fn(args) {}     // 等同于     function fn(args) {         // spawn函數就是自動執行器         return spawn(function* () {});     } </script>
登錄后復制

我們可以分析一下 Generator 和 async 代碼的書寫特點和風格:

<script>     // Generator 函數     function Generator(a, b) {         return spawn(function*() {             let r = null;             try {                 for(let k of b) {                 r = yield k(a);                 }             } catch(e) {                 /* 忽略錯誤,繼續執行 */             }             return r;         });     }       // async 函數     async function async(a, b) {         let r = null;         try {             for(let k of b) {             r = await k(a);             }         } catch(e) {          /* 忽略錯誤,繼續執行 */         }         return r;     } </script>
登錄后復制

所以 async 函數的實現符合語義也很簡潔,不用寫Generator的自動執行器,改在語言底層提供,因此代碼量少。

從上文代碼我們可以總結以下幾點

(1)Generator函數執行需要借助執行器,而async函數自帶執行器,即async不需要像生成器一樣需要借助 next 方法才能執行,而是會自動執行。

(2)相比于生成器函數,我們可以看到 async 函數的語義更加清晰

(3)上面就說了,async函數可以接受Promise或者其他原始類型,而生成器函數yield命令后面只能是Promise對象或者Thunk函數。

(4)async函數返回值只能是Promise對象,而生成器函數返回值是 Iterator 對象

【推薦學習:javascript高級教程】

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
噜噜噜久久亚洲精品国产品小说| 亚洲精品韩国| 视频一区中文字幕精品 | 久久国产精品久久久久久电车| 欧美在线亚洲| 亚洲人成亚洲精品| 欧美日本二区| 福利精品在线| 欧美在线亚洲| 国产日韩高清一区二区三区在线 | 日韩国产欧美视频| 久久只有精品| 欧美天堂视频| 视频在线观看国产精品| 国产欧美丝祙| 少妇精品导航| 日韩va欧美va亚洲va久久| 麻豆成人av在线| 999久久久亚洲| 青青草91视频| 美女亚洲一区| 国产精品v亚洲精品v日韩精品| 日韩一区二区在线免费| 久久99伊人| 国产成人久久精品一区二区三区| 激情五月色综合国产精品| 日韩欧美中文字幕一区二区三区 | 国产九九精品| 少妇精品导航| 国产乱码精品一区二区三区四区 | 亚洲1区在线观看| 成人在线免费观看91| 欧美日韩国产精品一区二区亚洲| 日本免费在线视频不卡一不卡二| 成人羞羞在线观看网站| 久久国产三级精品| 欧美香蕉视频| 欧美日韩精品一区二区三区在线观看| 久久九九99| 麻豆精品在线播放| 性色av一区二区怡红| 久久精品一区二区国产| 老司机久久99久久精品播放免费| 精品国产精品国产偷麻豆| 亚洲中午字幕| av中文字幕在线观看第一页| 91伊人久久| 亚洲一区二区网站| 中国字幕a在线看韩国电影| 日本综合精品一区| 91久久久精品国产| 欧美精品1区| 日韩三级一区| 久久国产精品久久久久久电车| 日韩欧美三级| 日韩不卡一区| 国产精品tv| 亚洲精品进入| 日韩专区在线视频| 久久理论电影| 92国产精品| 国产成人精选| 精品淫伦v久久水蜜桃| 日本aⅴ亚洲精品中文乱码 | 精品一区亚洲| 中文字幕在线看片| 美女视频黄久久| 国产欧美91| 97久久亚洲| 亚洲麻豆一区| 在线精品福利| 亚洲一区二区三区高清不卡| 91精品国产91久久久久久黑人| 精品久久久网| 精品无人区麻豆乱码久久久| 久久国产精品美女| 欧美影院视频| 欧美日韩一区二区国产| 日韩福利在线观看| 免费在线看一区| 免费日韩av| 日韩中文字幕av电影| 亚洲一区国产| 亚洲日韩中文字幕一区| 视频一区欧美日韩| 亚洲女人av| 中文字幕亚洲精品乱码| 亚洲久久视频| 日韩精品a在线观看91| 日本一区福利在线| 久久国产精品免费精品3p| 国产日韩欧美三区| 免费观看亚洲天堂| 丁香六月综合| 日韩在线精品| 99视频精品视频高清免费| 激情欧美一区二区三区| 一区福利视频| 亚洲综合专区| 国产人成精品一区二区三| 国产精品视频首页| 国际精品欧美精品| 欧美成a人免费观看久久| 亚洲成人一区| 亚洲午夜免费| 国产精品日本一区二区三区在线 | 狂野欧美性猛交xxxx| 色乱码一区二区三区网站| 成午夜精品一区二区三区软件| 日韩深夜视频| 久色成人在线| 欧美日韩亚洲三区| 国产一区精品福利| 久久精品青草| 快she精品国产999| 91福利精品在线观看| 欧美极品中文字幕| 亚洲性色av| 综合激情婷婷| 精品国产亚洲一区二区三区在线 | 偷拍亚洲精品| 久久av免费| 午夜av成人| 久久国产精品久久久久久电车| 欧美视频一区| 亚洲天堂一区二区| 中文字幕一区二区三区日韩精品| 国产精品免费99久久久| 亚洲国产福利| 亚洲欧美日韩精品一区二区| 国产日韩高清一区二区三区在线 | 视频一区二区三区在线| 国产图片一区| 久久亚洲国产| 日韩精品一页| 日韩精品永久网址| 日韩精品一二三区| 欧美精品aa| 在线视频日韩| 里番精品3d一二三区| 欧美日韩黑人| 国产欧美一区二区三区精品观看 | 欧美不卡高清一区二区三区| 午夜电影亚洲| 欧美国产亚洲精品| 亚洲激情不卡| 岛国精品一区| 日日夜夜免费精品| 久久中文字幕av| 国产精品探花在线观看| 午夜欧美理论片| 日本一区二区免费高清| 石原莉奈在线亚洲三区| 波多视频一区| 国产精品亲子伦av一区二区三区 | 在线成人直播| 国产色99精品9i| 中文一区二区| 亚洲女同av| 久久av国产紧身裤| 免费看欧美美女黄的网站| 日韩av自拍| 欧美日韩亚洲一区三区| 好吊日精品视频| 91亚洲人成网污www| 青草国产精品| 免费人成精品欧美精品| 成人看片网站| 精品丝袜久久| 国产欧美高清视频在线| 蜜桃久久久久久久| 日韩高清中文字幕一区二区| 国产欧美日韩精品一区二区三区| 先锋亚洲精品| 欧美 日韩 国产精品免费观看| 久久亚洲黄色| 欧美日韩亚洲一区二区三区在线| 香蕉视频成人在线观看| 精品欧美激情在线观看| 国产精品久久久久久久免费观看| 欧美一级二级视频| 日韩精品午夜视频| 欧美专区一区二区三区| 日韩和的一区二在线| 久久香蕉网站| 国产精品一区二区三区美女| 久久午夜精品一区二区| 欧美一级精品| 91精品一区二区三区综合在线爱| 正在播放日韩精品| 精品国产美女a久久9999| 国产欧美91| 国产午夜一区| 久久国际精品| 国产精品大片免费观看| 国产日韩中文在线中文字幕 | 丝袜美腿亚洲一区| 偷拍欧美精品| 一区二区三区视频免费观看| 亚洲伦乱视频|