async await 處理非同步知多少

2022-09-06 11:54:19 字數 3810 閱讀 4444

先說一下async的用法,它作為乙個關鍵字放到函式前面,

async function

timeout()

只有乙個作用, 它的呼叫會返回乙個promise 物件。呼叫一下看看就知道了,怎麼呼叫?async 函式也是函式,所以它的呼叫和普通函式的呼叫沒有什麼區別,直接加括號呼叫就可以了,為了看結果,console.log 一下。

async function

timeout()

console.log(timeout());

看一下控制台:

async函式(timeout)的呼叫,確實返回promise 物件,並且promise 還有status和value,如果async 函式中有返回值 ,當呼叫該函式時,內部會呼叫promise.solve() 方法把它轉化成乙個promise 物件作為返回, 但如果timeout 函式內部丟擲錯誤呢?

async function

timeout()

console.log(timeout());

就會呼叫promise.reject() 返回乙個promise 物件,

那麼要想獲取到async 函式的執行結果,就要呼叫promise的then 或catch 來給它註冊**函式,

async function

timeout()

timeout().then(result =>)

如果async 函式執行完,返回的promise 沒有註冊**函式,比如函式內部做了一次for 迴圈,你會發現函式的呼叫,就是執行了函式體,和普通函式沒有區別,唯一的區別就是函式執行完會返回乙個promise 物件。

async function

timeout()

}console.log(timeout());

console.log('outer')

async 關鍵字差不多了,最重要的就是async函式的執行會返回乙個promise 物件,並且把內部的值進行promise的封裝。如果promise物件通過then或catch方法又註冊了**函式,async函式執行完以後,註冊的**函式就會放到非同步佇列中,等待執行。如果只是async,  和promise 差不多,但有了await就不一樣了, await 關鍵字只能放到async 函式裡面,await是等待的意思,那麼它等待什麼呢,它後面跟著什麼呢?其實它後面可以放任何表示式,不過我們更多的是放乙個返回promise 物件的表示式,它等待的是promise 物件的執行完畢,並返回結果

現在寫乙個函式,讓它返回promise 物件,該函式的作用是2s 之後讓數值乘以2。

//

2s 之後返回雙倍的值

function

doubleafter2seconds(num) , 2000);

} )}

現在再寫乙個async 函式,從而可以使用await 關鍵字, await 後面放置的就是返回promise物件的乙個表示式,所以它後面可以寫上 doubleafter2seconds 函式的呼叫。

async function

testresult()

現在呼叫testresult 函式

testresult();
開啟控制台,2s 之後,輸出了60. 

現在看看**的執行過程,呼叫testresult 函式,它裡面遇到了await, await 表示等待,**就暫停到這裡,不再向下執行了,它等待後面的promise物件執行完畢,然後拿到promise resolve 的值並進行返回,返回值拿到之後,它繼續向下執行。具體到 我們的**, 遇到await 之後,**就暫停執行了, 等待doubleafter2seconds(30) 執行完畢,doubleafter2seconds(30) 返回的promise 開始執行,2秒 之後,promise resolve 了, 並返回了值為60, 這時await 才拿到返回值60, 然後賦值給result, 暫停結束,**繼續執行,執行 console.log語句。

就這乙個函式,我們可能看不出async/await 的作用,如果我們要計算3個數的值,然後把得到的值進行輸出呢?

async function

testresult()

6秒後,控制台輸出220, 我們可以看到,寫非同步**就像寫同步**一樣了,再也沒有**地域了。

這裡強調一下等待,當js引擎在等待promise resolve 的時候,它並沒有真正的暫停工作,它可以處理其它的一些事情,如果我們在testresult函式的呼叫後面,console.log 一下,你發現 後面console.log的**先執行。

async function

testresult()

testresult();

console.log('先執行');

當使用者輸入**號碼後,先查詢這個**號碼所在的省和市,然後再根據省和市,找到可能充值的面值,進行展示。

我們來動態獲取充值面值。當點選確定按鈕時, 我們首先要根據手機號得到省和市,所以寫乙個方法來傳送請求獲取省和市,方法命名為getlocation, 接受乙個引數phonenum , 後台介面名為phonelocation,當獲取到城市位置以後,我們再傳送請求獲取充值面值,所以還要再寫乙個方法getfacelist, 它接受兩個引數, province 和city, 後台介面為facelist,在methods 下面新增這兩個方法getlocation, getfacelist。

methods: )

},//獲取面值

getfacelist(province, city) )

},//點選確定按鈕時,獲取面值列表

getfaceresult ()

}

前端頁面中的click 事件的getfaceresult, 由於axios 返回的是promise 物件,我們使用then 的鏈式寫法,先呼叫getlocation方法,在其then方法中獲取省和市,然後再在裡面呼叫getfacelist,再在getfacelist 的then方法獲取面值列表,

//

點選確定按鈕時,獲取面值列表

getfaceresult () })}

}).catch(err =>)

}

現在點選確定按鈕,可以看到頁面中輸出了 從後台返回的面值列表。這時你看到了then 的鏈式寫法,有一點**地域的感覺。現在我們在有async/ await 來改造一下。

首先把 getfaceresult 轉化成乙個async 函式,就是在其前面加async, 因為它的呼叫方法和普通函式的呼叫方法是一致,所以沒有什麼問題。然後就把 getlocation 和

getfacelist 放到await 後面,等待執行, getfaceresult  函式修改如下

//

點選確定按鈕時,獲取面值列表

async getfaceresult () }}

現在**的書寫方式,就像寫同步**一樣,沒有**的感覺,非常舒服。

現在就還差一點需要說明,那就是怎麼處理異常,如果請求發生異常,怎麼處理? 它用的是try/catch 來捕獲異常,把await 放到 try 中進行執行,如有異常,就使用catch 進行處理。

async getfaceresult () }} 

catch

(err)

}

async await處理非同步問題

在編寫網頁的時候我們常常會遇到非同步問題,async await是es6提出的解決非同步的方法,下面我們來看看這個方法怎麼實現解決非同步的,function foo 1000 console.log 2 答案肯定是2,1 因為settimeout是乙個非同步執行語句,所以下面乙個會先執行完後再執行非...

async await進行非同步處理

參考 await 只能出現在 async 函式中 async 函式返回的是乙個 promise 物件。async 函式 包含函式語句 函式表示式 lambda表示式 會返回乙個 promise 物件,如果在函式中return乙個直接量,async 會把這個直接量通過promise.resolve 封...

非同步async await寫法

async await 用asyncio提供的 asyncio.coroutine可以把乙個generator標記為coroutine型別,然後在coroutine內部用yield from呼叫另乙個coroutine實現非同步操作。為了簡化並更好地標識非同步io,從python 3.5開始引入了新...