async/await讓異步操作同步執(zhí)行的方法詳解
一.前言
我們經(jīng)常會遇到這樣的麻煩事,多個函數(shù)按順序執(zhí)行,返回結果卻不是我們預期的順序,原因一般是由于異步操作引起的,所以呢,我們需要一種解決方案來處理這種問題,從而使得異步操作按照同步的方式來執(zhí)行,這樣我們就可以控制異步操作輸出結果的順序了
二.異步操作會帶來什么問題
異步操作可能會許多的問題,下面是常見的兩種
1.函數(shù)執(zhí)行的結果并不是按照順序返回
function fn1(){ console.log(111) setTimeout(function(){ console.log('wait me 3000') },3000) } function fn2(){ console.log(222) } fn1(); fn2();
//結果
//111
//222
//wait me 3000
上面的代碼,如果你期待的結果是
//111
//wait me 3000
//222
那就錯了,因為fn1函數(shù)里面還有一個函數(shù)setTimeout,這兩個函數(shù)是異步執(zhí)行的,而fn1和fn2是同步執(zhí)行的,先執(zhí)行fn1再執(zhí)行fn2,在執(zhí)行fn1的時候打印結果111,三秒后再執(zhí)行setTimeout,但是在這三秒之前已經(jīng)執(zhí)行完了fn2
那是不是由于setTimeout函數(shù)設置的等待時間太久了才會導致的呢?那下面我把時間設為0
function fn1(){ console.log(111) setTimeout(function(){ console.log('wait me 3000') },0) } function fn2(){ console.log(222) } fn1(); fn2(); //結果 //111 //222 //wait me 3000
從結果上看并沒有改變,這是應為setTimeout這個函數(shù)在執(zhí)行之前會查看執(zhí)行隊列看看有沒有人在排隊,如果有,那么將等其他的函數(shù)執(zhí)行完再執(zhí)行自己,所以不管就算你設置時間為0,也不會改變它最后一個執(zhí)行
2.在外部獲取不到異步函數(shù)里的值
下面我們看一個最簡單的例子,我的需求是要在fn1函數(shù)外面打印msg
function fn1(){ setTimeout(function(){ msg='wait me 3000'; },3000); } fn1();
那么怎么樣才能獲取到msg呢
使用回調(diào)函數(shù)
function fn1(callback){ setTimeout(function(){ msg='wait me 3000'; callback(msg); },3000); } fn1(data=>{ console.log(data);//wait me 3000 });
使用Promise
function fn1(){ return new Promise(function(res,rej){ setTimeout(function(){ msg='wait me 3000'; res(msg); },3000); }) } fn1().then(data=>{ console.log(data) })
三.async/await解決方案
async/await的作用就是使異步操作以同步的方式去執(zhí)行
異步操作同步化?
可以使用Promise中的then()來實現(xiàn),那么async/await與它之間有什么區(qū)別呢
1.async函數(shù)返回的是一個Promise對象
如果一個函數(shù)加了async關鍵詞,這個函數(shù)又有返回值,在調(diào)用這個函數(shù)時,如果函數(shù)執(zhí)行成功,內(nèi)部會調(diào)用Promise.solve()方法返回一個Promise對象,如果函數(shù)執(zhí)行出現(xiàn)異常,就會調(diào)用Promise.reject()方法返回一個promise 對象
要想獲取到async函數(shù)的執(zhí)行結果,就要調(diào)用Promise的then或catch來給它注冊回調(diào)函數(shù)
async function fn(){ return '111' } console.log(fn());//Promise { '111' }
既然是Promise對象,因此可以使用then()獲取返回的結果
async function fn(){ return '111' } fn().then(data=>{ console.log(data)//111 })
2.await
上面介紹了async的作用,一般情況下,async與await配合使用才能使異步操作同步化,await就是等待的意思,等待某一個函數(shù)執(zhí)行完之后,后面的代碼才能開始執(zhí)行
function fn1(){ return new Promise(resolve=>{ setTimeout(function(){ msg='wait me 3000'; resolve(msg) },3000); }); } async function asyncCall(){ var result=await fn1(); console.log(result); } asyncCall();
如果我們沒有等待fn1執(zhí)行完之后再打印result,那么有可能得到是undefined
四.總結
在很多的時候,我們是希望按照同步的方式來獲得異步函數(shù)的結果,比如登錄時,我們必須要在后臺返回匹配成功的信息之后才能進行頁面跳轉,因此,使異步操作同步化這是很重要的知識點,但是這種方案是基于Promise的基礎之上的,因此在學習該知識時,一定要對Promise有充分的理解
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
相關文章
原生javascript自定義input[type=radio]效果示例
這篇文章主要介紹了原生javascript自定義input[type=radio]效果,結合實例形式分析了javascript模擬form表單中radio效果的相關操作技巧,需要的朋友可以參考下2019-08-08通過location.replace禁止瀏覽器后退防止重復提交
如果用戶重復提交事件,然后又后退,這樣可能會對某些數(shù)據(jù)產(chǎn)生災難性的問題。所以今天就向大家介紹一種通過location.replace禁止瀏覽器后退按鈕的方法2014-09-09原生js實現(xiàn)網(wǎng)頁頂部自動下拉/收縮廣告效果
本文主要介紹了原生js實現(xiàn)網(wǎng)頁頂部自動下拉/收縮廣告效果的實例代碼。具有一定的參考價值,下面跟著小編一起來看下吧2017-01-01