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

