一.前言
我們經常會遇到這樣的麻煩事,多個函數按順序執行,返回結果卻不是我們預期的順序,原因一般是由于異步操作引起的,所以呢,我們需要一種解決方案來處理這種問題,從而使得異步操作按照同步的方式來執行,這樣我們就可以控制異步操作輸出結果的順序了
二.異步操作會帶來什么問題
異步操作可能會許多的問題,下面是常見的兩種
1.函數執行的結果并不是按照順序返回
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
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
function fn1(){ setTimeout(function(){ msg='wait me 3000'; },3000);}fn1();
那么怎么樣才能獲取到msg呢
使用回調函數
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的作用就是使異步操作以同步的方式去執行
異步操作同步化?
可以使用Promise中的then()來實現,那么async/await與它之間有什么區別呢
1.async函數返回的是一個Promise對象
如果一個函數加了async關鍵詞,這個函數又有返回值,在調用這個函數時,如果函數執行成功,內部會調用Promise.solve()方法返回一個Promise對象,如果函數執行出現異常,就會調用Promise.reject()方法返回一個promise 對象
要想獲取到async函數的執行結果,就要調用Promise的then或catch來給它注冊回調函數
async function fn(){ return '111'}console.log(fn());//Promise { '111' }
既然是Promise對象,因此可以使用then()獲取返回的結果
新聞熱點
疑難解答