摘要:認(rèn)識(shí)首先要從單個(gè)熟悉官方介紹聲明將定義一個(gè)返回對(duì)象的異步函數(shù)。
認(rèn)識(shí)async await 首先要從單個(gè)熟悉
async
官方介紹:
async function?聲明將定義一個(gè)返回?AsyncFunction?對(duì)象的異步函數(shù)。
個(gè)人理解:
1. 首先`async function`會(huì)申明定義一個(gè)異步執(zhí)行的函數(shù),無阻塞,不會(huì)阻塞后面代碼執(zhí)行 2. 該函數(shù)的返回值是一個(gè)Promise對(duì)象
執(zhí)行以下代碼
async function testAsync() { return "茶樹菇" } console.log(testAsync()); /*打印結(jié)果: Promise result: "茶樹菇" status: "resolved" “Promise”原型*/
打印結(jié)果可以看出,async 可以將其后的函數(shù)執(zhí)行結(jié)果轉(zhuǎn)為Promise對(duì)象
既然如此那以下操作也是可行的
testAsync().then(r => { console.log(r); });//"茶樹菇"
由以下打印結(jié)果可知async function聲明函數(shù)是異步函數(shù)
function t() { return new Promise(resolve => { resolve("hah") }) } async function t1() { const a = await t() // console.log(a); console.log("t1函數(shù)里"); } t1() console.log("我在t1函數(shù)調(diào)用后"); /*打印結(jié)果: [Log] 我在t1函數(shù)調(diào)用后 [Log] t1函數(shù)里 */
await
官方介紹:
await? 操作符用于等待一個(gè)Promise?對(duì)象。它只能在異步函數(shù)?async function?中使用。
個(gè)人理解:
官方注釋await是在等待一個(gè)Promise對(duì)象,其實(shí)沒有限制,只是根據(jù)等待到的結(jié)果類型的不同有不同的操作,如果等到的就是個(gè)結(jié)果,則await就返回這個(gè)值,如果等到的是一Promise對(duì)象,則await會(huì)阻塞后面代碼執(zhí)行,等待Promise的結(jié)果(由于await在async function申明的異步執(zhí)行函數(shù),所以不會(huì)影響該函數(shù)外的其他代碼執(zhí)行,只影響內(nèi)部)
注意:如果await等待的Promise執(zhí)行結(jié)果除了resolve外,還有異常處理reject,則最好用.catch(err => err)去接收處理異常, 例const a = await t().catch(err => err)
async function testAsync1() { return "茶樹菇"; } function testAsync2() { return new Promise(resolve => { resolve("茶樹菇") }) } function testAsync3() { return "茶樹菇"; } async function testFn() { const v1 = await testAsync1(); const v2 = await testAsync2(); const v3 = await testAsync3(); console.log(v1);//"茶樹菇" console.log(v2);//"茶樹菇" console.log(v3);//"茶樹菇" //由此可見`await`等待的不一定是個(gè)`Promise`對(duì)象,也可以是個(gè)值 } testFn();
為什么用async await,對(duì)比Promise的優(yōu)缺點(diǎn)在哪?
模擬個(gè)使用場景,如下代碼
需求:隨機(jī)產(chǎn)生一個(gè)1~2之間的隨機(jī)數(shù),用延時(shí)器模擬異步操作,判斷該值,如果小于一就成功,大于一失敗
//用Promise實(shí)現(xiàn): function test(resolve, reject) { var timeOut = Math.random() * 2; console.log("隨機(jī)數(shù)為:" + timeOut); setTimeout(function() { if (timeOut < 1) { resolve("小于1, 成功") } else { reject("大于1,失敗") } }, timeOut * 1000) } new Promise(test).then((result) => { console.log(result); }).catch((reason) => { console.log(reason); })
打印結(jié)果:
function test2() { var timeOut = Math.random() * 2; console.log("隨機(jī)數(shù)為:" + timeOut); return new Promise((resolve, reject) => { setTimeout(() => { if (timeOut < 1) { resolve("小于1, 成功") } else { reject("大于1,失敗") } }, 1000) }) } async function asyncFn() { const v3 = await test2().catch(er => er) console.log(v3); } asyncFn()
看代碼其實(shí)單一的異步處理鏈并不能看出async await的優(yōu)勢,但是如果需要處理多個(gè)Promise組成的處理鏈,就能看出區(qū)別
假設(shè)需求為:分布完成,每一步都需要上一步的結(jié)果:
//每次調(diào)用時(shí)間都增加200 function logTimeOut(n) { return new Promise(resolve => { setTimeout(() => resolve(n + 200), n) }) } //第一步 function stepOne(n) { console.log("第一步所用的時(shí)間", n); return logTimeOut(n) } //第二步將第一步的結(jié)果加上200作為第二部的初始時(shí)間 function stepTow(m, n) { console.log("第二部所用的時(shí)間",m, n); return logTimeOut(n + m) } //第三步將第二步的結(jié)果加上200作為第三步的初始時(shí)間 function stepThree(k, m, n) { console.log("第三部所用的時(shí)間", k, m, n); return logTimeOut(k + m + n) }
首先用Promise實(shí)現(xiàn)
//promise實(shí)現(xiàn) function doIt() { console.time("doIt"); // 第一步初始時(shí)間 const time1 = 200; stepOne(time1).then(time2 => { return stepTow(time1, time2).then(time3 => [time1, time2, time3]) }) .then(timeArr => { const [time1, time2, time3] = timeArr return stepThree(time1, time2, time3) }) .then(result => { console.log("總共計(jì)算用時(shí)", result); console.timeEnd("doIt") }) } doIt()
使用async awiat:
// async await 實(shí)現(xiàn) async function startIt() { console.time("startIt") const time1 = 200; const time2 = await stepOne(time1) const time3 = await stepTow(time1, time2) const result = await stepThree(time1, time2, time3) console.log("總共計(jì)算用時(shí)", result); console.timeEnd("startIt") }
打印結(jié)果:
這樣對(duì)比就能明顯看出區(qū)別Promise實(shí)現(xiàn)的代碼邏輯復(fù)雜,不清晰,不直觀,而通過async await,可以將異步邏輯,用類似于同步的代碼實(shí)現(xiàn),簡潔明了
這是到目前為止的個(gè)人理解,轉(zhuǎn)載請(qǐng)標(biāo)明出處
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99447.html
摘要:下面將簡單地描述一下一些日常常用場景加深對(duì)認(rèn)識(shí)最普遍的異步操作就是請(qǐng)求我們也可以用來簡單模擬異步請(qǐng)求。其中是必須的如果省略了程序就不能按預(yù)期得到結(jié)果。 前言 async/await 語法用看起來像寫同步代碼的方式來優(yōu)雅地處理異步操作,但是我們也要明白一點(diǎn),異步操作本來帶有復(fù)雜性,像寫同步代碼的方式并不能降低本質(zhì)上的復(fù)雜性,所以在處理上我們要更加謹(jǐn)慎, 稍有不慎就可能寫出不是預(yù)期執(zhí)行的代...
摘要:下面將簡單地描述一下一些日常常用場景加深對(duì)認(rèn)識(shí)最普遍的異步操作就是請(qǐng)求我們也可以用來簡單模擬異步請(qǐng)求。其中是必須的如果省略了程序就不能按預(yù)期得到結(jié)果。 前言 async/await 語法用看起來像寫同步代碼的方式來優(yōu)雅地處理異步操作,但是我們也要明白一點(diǎn),異步操作本來帶有復(fù)雜性,像寫同步代碼的方式并不能降低本質(zhì)上的復(fù)雜性,所以在處理上我們要更加謹(jǐn)慎, 稍有不慎就可能寫出不是預(yù)期執(zhí)行的代...
摘要:下面將簡單地描述一下一些日常常用場景加深對(duì)認(rèn)識(shí)最普遍的異步操作就是請(qǐng)求我們也可以用來簡單模擬異步請(qǐng)求。其中是必須的如果省略了程序就不能按預(yù)期得到結(jié)果。 前言 async/await 語法用看起來像寫同步代碼的方式來優(yōu)雅地處理異步操作,但是我們也要明白一點(diǎn),異步操作本來帶有復(fù)雜性,像寫同步代碼的方式并不能降低本質(zhì)上的復(fù)雜性,所以在處理上我們要更加謹(jǐn)慎, 稍有不慎就可能寫出不是預(yù)期執(zhí)行的代...
摘要:前言最近公司要開發(fā)一款電商小程序,匆忙看了一遍文檔就開始干活了。整體開發(fā)體驗(yàn)個(gè)人感覺不太好,特別是如果之前習(xí)慣了開發(fā),突然去開發(fā)小程序,感覺很雞肋。 前言 最近公司要開發(fā)一款電商小程序,匆忙看了一遍文檔就開始干活了。整體開發(fā)體驗(yàn)個(gè)人感覺不太好,特別是如果之前習(xí)慣了Vue開發(fā),突然去開發(fā)小程序,感覺很雞肋。以下是我在開發(fā)中遇到的一些問題以及解決方法的總結(jié),僅供參考 引入iconfont ...
摘要:輔之以事件循環(huán),協(xié)程可用于異步處理,尤其是在中。當(dāng)前支持的協(xié)程基于增強(qiáng)型生成器,于版本開始采用。新的特性中,異步還有兩種新用途異步內(nèi)容管理器和迭代器。 現(xiàn)在 Python 已經(jīng)支持用協(xié)程進(jìn)行異步處理。但最近有建議稱添加協(xié)程以全面完善 Python 的語言結(jié)構(gòu),而不是像現(xiàn)在這樣把他們作為生成器的一個(gè)類型。此外,兩個(gè)新的關(guān)鍵字———異步(async)和等待(await),都該添加到 Pyt...
閱讀 2258·2023-04-26 01:50
閱讀 714·2021-09-22 15:20
閱讀 2595·2019-08-30 15:53
閱讀 1596·2019-08-30 12:49
閱讀 1714·2019-08-26 14:05
閱讀 2713·2019-08-26 11:42
閱讀 2309·2019-08-26 10:40
閱讀 2602·2019-08-26 10:38