當(dāng)我還在使用promise來發(fā)送異步請求的時(shí)候,部門前端大佬已經(jīng)改用async/ await了蠢棱,代碼很簡潔锌杀,同時(shí)async/await 已經(jīng)被標(biāo)準(zhǔn)化甩栈,是時(shí)候?qū)W習(xí)一下了~
一、async函數(shù)介紹
async 是 ES7 才有的與異步操作有關(guān)的關(guān)鍵字糕再,和 Promise量没,Generator 有很大關(guān)聯(lián)的。
【1】特點(diǎn):
1突想、建立在 promise 之上殴蹄。所以,不能把它和回調(diào)函數(shù)搭配使用猾担。但它會(huì)聲明一個(gè)異步函數(shù)袭灯,并隱式地返回一個(gè)Promise。因此可以直接return變量绑嘹,無需使用 Promise.resolve 進(jìn)行轉(zhuǎn)換稽荧。
2、和 promise 一樣圾叼,是非阻塞的蛤克。但不用寫 then 及其回調(diào)函數(shù)捺癞,這減少代碼行數(shù)夷蚊,也避免了代碼嵌套。而且髓介,所有異步調(diào)用惕鼓,可以寫在同一個(gè)代碼塊中,無需定義多余的中間變量唐础。
3箱歧、它的最大價(jià)值在于,可以使異步代碼一膨,在形式上呀邢,更接近于同步代碼。
4豹绪、它總是與 await 一起使用的价淌。并且await 只能在 async 函數(shù)體內(nèi)。
5瞒津、await 是個(gè)運(yùn)算符蝉衣,用于組成表達(dá)式,它會(huì)阻塞后面的代碼巷蚪。如果等到的是 Promise 對象病毡,則得到其 resolve 值。否則屁柏,會(huì)得到一個(gè)表達(dá)式的運(yùn)算結(jié)果啦膜。
【2】用法:
先說一下async的用法有送,它作為一個(gè)關(guān)鍵字放到函數(shù)前面,用于表示函數(shù)是一個(gè)異步函數(shù)功戚,因?yàn)閍sync就是異步的意思娶眷, 異步函數(shù)也就意味著該函數(shù)的執(zhí)行不會(huì)阻塞后面代碼的執(zhí)行。 下面我們就來寫一個(gè)async 函數(shù)
async function test() {
return 'Hello World';
}
console.log(test())
語法很簡單啸臀,就是在函數(shù)前面加上async 關(guān)鍵字届宠,來表示它是異步的,那怎么調(diào)用呢乘粒?async 函數(shù)也是函數(shù)豌注,平時(shí)我們怎么使用函數(shù)就怎么使用它,直接加括號(hào)調(diào)用就可以了
查看控制臺(tái)打印結(jié)果
原來async 函數(shù)返回的是一個(gè)promise 對象灯萍,如果要獲取到promise 返回值轧铁,我們應(yīng)該用then 方法, 繼續(xù)修改代碼
async function test() {
return 'Hello World';
}
test().then(res=>{
console.log(res) // Hello World
})
console.log('我在后面旦棉,但是我先執(zhí)行')
上面代碼中通過then()方法獲取到promise的返回值齿风,假設(shè)promise內(nèi)部拋出異常,我們同樣可以通過catch()方法來捕獲異常绑洛。
我們獲取到了"Hello World', 同時(shí)test()異步函數(shù)的執(zhí)行也沒有阻塞后面代碼的執(zhí)行救斑,"我在后面,但是我先執(zhí)行"真屯,這條語句會(huì)先執(zhí)行
看到這脸候,小伙伴們可能要納悶了,就是封裝一個(gè)Promise的對象返回而已绑蔫,要這有個(gè)鬼用啊运沦。別急,接下來有請async黃金搭檔 await關(guān)鍵字閃亮登場配深。
二携添、await關(guān)鍵字
await是等待的意思,那么它等待什么呢篓叶,它后面跟著什么呢烈掠?
正常情況下,await 命令后面是一個(gè) Promise 對象澜共,它也可以跟其他值向叉,如字符串,布爾值嗦董,數(shù)值以及普通函數(shù)母谎。await表達(dá)式會(huì)使async函數(shù)暫停執(zhí)行,等待promise的結(jié)果出來京革,然后恢復(fù)async的執(zhí)行并返回解析值(resolved)
注意奇唤,await 關(guān)鍵字僅僅在async 函數(shù)中才有效幸斥,如果在async函數(shù)外使用await,則會(huì)拋出一個(gè)語法錯(cuò)誤(SyntaxError)
function testAwait() {
return new Promise((resolve) => {
setTimeout(function () {
console.log("Test Await");
resolve();
}, 1000);
});
}
async function test() {
await testAwait();
console.log("Hello World");
}
test();
// Test Await
// Hello World
我們來分析下上面這段代碼
現(xiàn)在我們看看代碼的執(zhí)行過程咬扇,調(diào)用test函數(shù)甲葬,它里面遇到了await, await 表示等一下,代碼就暫停到這里懈贺,不再向下執(zhí)行了经窖,它等什么呢?等后面的testAwait函數(shù)中的promise對象執(zhí)行完畢梭灿,然后拿到promise resolve 的值并進(jìn)行返回画侣,返回值拿到之后,它繼續(xù)向下執(zhí)行堡妒。執(zhí)行console.log語句配乱。
注意:await 命令后面的 Promise 對象,運(yùn)行結(jié)果不一定都是resolve皮迟,也可能是 rejected搬泥。當(dāng)promise返回結(jié)果為rejected狀態(tài)時(shí),會(huì)終止后面的代碼執(zhí)行伏尼。所以最好把 await 命令放在 try...catch 代碼塊中忿檩。異常被try...catch捕獲后,繼續(xù)執(zhí)行下面的代碼烦粒,不會(huì)導(dǎo)致中斷
function testAwait() {
return new Promise((resolve) => {
setTimeout(function () {
console.log("Test Await");
resolve();
}, 1000);
});
}
async function test() {
try {
await testAwait();
} catch (err) {
console.log(err)
}
console.log("Hello World");
}
test();
文章每周持續(xù)更新休溶,可以微信搜索「 前端大集錦 」第一時(shí)間閱讀代赁,回復(fù)【視頻】【書籍】領(lǐng)取200G視頻資料和30本PDF書籍資料