async/await讓異步操做同步執行

一.前言

咱們常常會遇到這樣的麻煩事,多個函數按順序執行,返回結果卻不是咱們預期的順序,緣由通常是因爲異步操做引發的,因此呢,咱們須要一種解決方案來處理這種問題,從而使得異步操做按照同步的方式來執行,這樣咱們就能夠控制異步操做輸出結果的順序了promise

二.異步操做會帶來什麼問題

異步操做可能會許多的問題,下面是常見的兩種bash

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,這兩個函數是異步執行的,而fn1fn2是同步執行的,先執行fn1再執行fn2,在執行fn1的時候打印結果111,三秒後再執行setTimeout,可是在這三秒以前已經執行完了fn2async

那是否是因爲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函數外面打印msgui

function fn1(){
    setTimeout(function(){
       msg='wait me 3000';
    },3000);
}
fn1();
複製代碼

那麼怎麼樣才能獲取到msgspa

使用回調函數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解決方案

async/await的做用就是使異步操做以同步的方式去執行

異步操做同步化?

可使用Promise中的then()來實現,那麼async/await與它之間有什麼區別呢

1.async函數返回的是一個Promise對象

若是一個函數加了async關鍵詞,這個函數又有返回值,在調用這個函數時,若是函數執行成功,內部會調用Promise.solve()方法返回一個Promise對象,若是函數執行出現異常,就會調用Promise.reject()方法返回一個promise 對象

要想獲取到async函數的執行結果,就要調用Promisethencatch來給它註冊回調函數

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的做用,通常狀況下,asyncawait配合使用才能使異步操做同步化,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有充分的理解

相關文章
相關標籤/搜索