認識async await 首先要從單個熟悉promise
官方介紹:async function
聲明將定義一個返回 AsyncFunction
對象的異步函數。
我的理解:dom
1. 首先`async function`會申明定義一個異步執行的函數,無阻塞,不會阻塞後面代碼執行 2. 該函數的返回值是一個Promise對象
執行如下代碼異步
async function testAsync() { return '茶樹菇' } console.log(testAsync()); /*打印結果: Promise result: "茶樹菇" status: "resolved" 「Promise」原型*/
打印結果能夠看出,async 能夠將其後的函數執行結果轉爲Promise
對象
既然如此那如下操做也是可行的async
testAsync().then(r => { console.log(r); });//"茶樹菇"
由如下打印結果可知async function
聲明函數是異步函數函數
function t() { return new Promise(resolve => { resolve('hah') }) } async function t1() { const a = await t() // console.log(a); console.log('t1函數裏'); } t1() console.log('我在t1函數調用後'); /*打印結果: [Log] 我在t1函數調用後 [Log] t1函數裏 */
官方介紹:await
操做符用於等待一個Promise
對象。它只能在異步函數 async function
中使用。spa
我的理解:
官方註釋await
是在等待一個Promise對象,其實沒有限制,只是根據等待到的結果類型的不一樣有不一樣的操做,若是等到的就是個結果,則await
就返回這個值,若是等到的是一Promise
對象,則await
會阻塞後面代碼執行,等待Promise
的結果(因爲await
在async function
申明的異步執行函數,因此不會影響該函數外的其餘代碼執行,隻影響內部)
注意:若是await
等待的Promise
執行結果除了resolve
外,還有異常處理reject
,則最好用.catch(err => err)
去接收處理異常, 例const a = await t().catch(err => err)
code
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`等待的不必定是個`Promise`對象,也能夠是個值 } testFn();
async await
,對比Promise
的優缺點在哪?模擬個使用場景,以下代碼
需求:隨機產生一個1~2之間的隨機數,用延時器模擬異步操做,判斷該值,若是小於一就成功,大於一失敗對象
//用Promise實現: function test(resolve, reject) { var timeOut = Math.random() * 2; console.log('隨機數爲:' + 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); })
打印結果:ip
function test2() { var timeOut = Math.random() * 2; console.log('隨機數爲:' + 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()
看代碼其實單一的異步處理鏈並不能看出async await
的優點,可是若是須要處理多個Promise
組成的處理鏈,就能看出區別
假設需求爲:分佈完成,每一步都須要上一步的結果:rem
//每次調用時間都增長200 function logTimeOut(n) { return new Promise(resolve => { setTimeout(() => resolve(n + 200), n) }) } //第一步 function stepOne(n) { console.log('第一步所用的時間', n); return logTimeOut(n) } //第二步將第一步的結果加上200做爲第二部的初始時間 function stepTow(m, n) { console.log('第二部所用的時間',m, n); return logTimeOut(n + m) } //第三步將第二步的結果加上200做爲第三步的初始時間 function stepThree(k, m, n) { console.log('第三部所用的時間', k, m, n); return logTimeOut(k + m + n) }
首先用Promise
實現
//promise實現 function doIt() { console.time("doIt"); // 第一步初始時間 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('總共計算用時', result); console.timeEnd('doIt') }) } doIt()
使用async awiat
:
// async await 實現 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('總共計算用時', result); console.timeEnd('startIt') }
打印結果:
這樣對比就能明顯看出區別Promise
實現的代碼邏輯複雜,不清晰,不直觀,而經過async await
,能夠將異步邏輯,用相似於同步的代碼實現,簡潔明瞭
這是到目前爲止的我的理解,轉載請標明出處