這篇文章主要給大家介紹了關於async/await讓異步操作同步執行的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者使用async/await具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
一.前言
我們經常會遇到這樣的麻煩事,多個函數按順序執行,返回結果卻不是我們預期的順序,原因一般是由於異步操作引起的,所以呢,我們需要一種解決方案來處理這種問題,從而使得異步操作按照同步的方式來執行,這樣我們就可以控制異步操作輸出結果的順序了
二.異步操作會帶來什么問題
異步操作可能會許多的問題,下面是常見的兩種
1.函數執行的結果並不是按照順序返回
1
2
3
4
5
6
7
8
9
10
11
|
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函數里面還有一個函數setTimeout,這兩個函數是異步執行的,而fn1和fn2是同步執行的,先執行fn1再執行fn2,在執行fn1的時候打印結果111,三秒后再執行setTimeout,但是在這三秒之前已經執行完了fn2
那是不是由於setTimeout函數設置的等待時間太久了才會導致的呢?那下面我把時間設為0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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這個函數在執行之前會查看執行隊列看看有沒有人在排隊,如果有,那么將等其他的函數執行完再執行自己,所以不管就算你設置時間為0,也不會改變它最后一個執行
2.在外部獲取不到異步函數里的值
下面我們看一個最簡單的例子,我的需求是要在fn1函數外面打印msg
1
2
3
4
5
6
|
function
fn1(){
setTimeout(
function
(){
msg=
'wait me 3000'
;
},3000);
}
fn1();
|
那么怎么樣才能獲取到msg呢
使用回調函數
1
2
3
4
5
6
7
8
9
|
function
fn1(callback){
setTimeout(
function
(){
msg=
'wait me 3000'
;
callback(msg);
},3000);
}
fn1(data=>{
console.log(data);
//wait me 3000
});
|
使用Promise
1
2
3
4
5
6
7
8
9
10
11
|
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的作用就是使異步操作以同步的方式去執行
異步操作同步化?
可以使用Promise中的then()來實現,那么async/await與它之間有什么區別呢
1.async函數返回的是一個Promise對象
如果一個函數加了async關鍵詞,這個函數又有返回值,在調用這個函數時,如果函數執行成功,內部會調用Promise.solve()方法返回一個Promise對象,如果函數執行出現異常,就會調用Promise.reject()方法返回一個promise 對象
要想獲取到async函數的執行結果,就要調用Promise的then或catch來給它注冊回調函數
1
2
3
4
|
async
function
fn(){
return
'111'
}
console.log(fn());
//Promise { '111' }
|
既然是Promise對象,因此可以使用then()獲取返回的結果
1
2
3
4
5
6
|
async
function
fn(){
return
'111'
}
fn().then(data=>{
console.log(data)
//111
})
|
2.await
上面介紹了async的作用,一般情況下,async與await配合使用才能使異步操作同步化,await就是等待的意思,等待某一個函數執行完之后,后面的代碼才能開始執行
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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執行完之后再打印result,那么有可能得到是undefined
四.總結
在很多的時候,我們是希望按照同步的方式來獲得異步函數的結果,比如登錄時,我們必須要在后台返回匹配成功的信息之后才能進行頁面跳轉,因此,使異步操作同步化這是很重要的知識點,但是這種方案是基於Promise的基礎之上的,因此在學習該知識時,一定要對Promise有充分的理解
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。