咱們常常會遇到這樣的麻煩事,多個函數按順序執行,返回結果卻不是咱們預期的順序,緣由通常是因爲異步操做引發的,因此呢,咱們須要一種解決方案來處理這種問題,從而使得異步操做按照同步的方式來執行,這樣咱們就能夠控制異步操做輸出結果的順序了promise
異步操做可能會許多的問題,下面是常見的兩種bash
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
async
那是否是因爲setTimeout
函數設置的等待時間過久了纔會致使的呢?那下面我把時間設爲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
這個函數在執行以前會查看執行隊列看看有沒有人在排隊,若是有,那麼將等其餘的函數執行完再執行本身,因此無論就算你設置時間爲0,也不會改變它最後一個執行學習
下面咱們看一個最簡單的例子,個人需求是要在fn1
函數外面打印msg
ui
function fn1(){
setTimeout(function(){
msg='wait me 3000';
},3000);
}
fn1();
複製代碼
那麼怎麼樣才能獲取到msg
呢spa
使用回調函數code
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的做用就是使異步操做以同步的方式去執行
異步操做同步化?
可使用Promise中的then()來實現,那麼async/await與它之間有什麼區別呢
若是一個函數加了async
關鍵詞,這個函數又有返回值,在調用這個函數時,若是函數執行成功,內部會調用Promise.solve()
方法返回一個Promise
對象,若是函數執行出現異常,就會調用Promise.reject()
方法返回一個promise
對象
要想獲取到async
函數的執行結果,就要調用Promise
的then
或catch
來給它註冊回調函數
async function fn(){
return '111'
}
console.log(fn());//Promise { '111' }
複製代碼
既然是Promise
對象,所以可使用then()
獲取返回的結果
async function fn(){
return '111'
}
fn().then(data=>{
console.log(data)//111
})
複製代碼
上面介紹了async
的做用,通常狀況下,async
與await
配合使用才能使異步操做同步化,await
就是等待的意思,等待某一個函數執行完以後,後面的代碼才能開始執行
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
有充分的理解