async與await的用法詳解


文章出自個人博客https://knightyun.github.io/2019/08/02/js-async-await,轉載請申明


async

用於聲明異步函數,返回值爲一個 Promise 對象,它以類似同步的方法來寫異步方法,語法與聲明函數類似,例如:

async function fn() {
    console.log('Hello world!');
}

console.log(fn().constructor); // Promise()
// 這裏證明其返回值爲一個 Promise 對象;

也許會有疑問,返回值是 Promise 對象,那麼函數本身定義的返回值跑到哪裏去了呢?其實,熟悉 Promise 的就知道其異步結果是通過 .then() 或者 .catch() 方法來獲取並進行進一步處理的,這樣一個道理,定義的異步函數中的返回值會當成 resolve 狀態來處理,一般用 .then() 方法處理,而如果定義的異步函數拋出錯誤,例如變量未定義,則會被當做 reject 狀態來處理,一般使用 .catch() 方法來處理;

舉例:

// 使用 .then() 的情況
async function fn1() {
    return 'Hello world!';
}

fn1().then(function(res) {
    console.log(res);
});
// Hello world!

// 使用 .catch() 的情況
async function fn2() {
    console.log(aaa); // 這裏的變量 aaa 未定義,爲了製造錯誤
}

fn2().catch(function(error) {
    console.log(error);
});
// ReferenceError: aaa is not defined

假如是既有返回值,又有錯誤的話,來看看結果如何:

async function fn3(){
    console.log(aaa); // aaa 依然未定義;
    return 'Hello world!';
}

fn3().then(function(res){
    console.log(res);
}).catch(function(error){
    console.log(error);
});
// ReferenceError: aaa is not defined

結果證明只會執行 reject 狀態的情況下的語句,忽略了 resolve 時的代碼,所以此處值得 注意

await

用法顧名思義,有等待的意思,語法爲:

var value = await myPromise();

注意 await 必須在 async function 內使用,否則會提示語法錯誤;

這裏的 myPromise() 是一個 Promise對象,而自定義的變量 value 則用於獲取 Promise 對象返回的 resolve 狀態值,如果 await 後面跟的是其他值,則直接返回該值;

所以,所謂等待其實就是指暫停當前 async function 內部語句的執行,等待後面的 Promise 處理完返回結果後,繼續執行 async function 函數內部的剩餘語句;

舉例:

async function fn(){
    console.log(1);
    var result = await new Promise(function(resolve, reject){
        setTimeout(function(){
            resolve(2);
        }, 2000);
    });
	console.log(result);
    console.log(3);
    console.log(await 4); // 4 會被直接返回
}
fn();
// 1
// 2 (2 秒後輸出)
// 3
// 4

如果 await 後面的 Promise 返回一個 reject 狀態的結果的話,則會被當成錯誤在後臺拋出,例如:

async function fn(){
    console.log(1);
    var result = await new Promise(function(resolve, reject){
        setTimeout(function(){
            reject(2);
        }, 2000);
    });
    console.log(3);
}
fn();
// 1
// Uncaught (in promise) 2 (2 秒後輸出)

如上,2 秒後會拋出出錯誤,並且 3 這個數並沒有被輸出,說明後面的執行也被忽略了;

另外,await 後面的 Promise 返回的 reject, 也可以被該 async 函數返回的 Promise 對象以 reject 狀態獲取,例如:

async function fn(){
    console.log(1);
    var result = await new Promise(function(resolve, reject){
        setTimeout(function(){
            reject(2);
        }, 2000);
    });
    console.log(3);
}
fn().catch(function(error){
    console.log(error);
});
// 1
// 2 (2 秒後輸出)

這種情況就不會以錯誤拋出,直接對異常值進行了處理,並且最後同樣沒有輸出數字 3,即後面的代碼依然被忽略了;


技術文章推送
手機、電腦實用軟件分享
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章