前言
js有很多異步處理的解決方案,哪個好那個壞誰也說不清,而 ES
中所包含的async
函數,卻是讓人感到眼前一亮,找到了解決 JavaScript 對於異步操作的最好操作,完美的可通過 Async
和 Await
輕鬆的進行扁平化處理。
async/await是什麼?
async/await
從字面意思上很好理解,async
是異步的意思,await有等待的意思,而兩者的用法上也是如此。async
用於申明一個function
是異步的,而await
用於等待一個異步方法執行完成。
也就是這樣一個過程:
async
表示這是一個async
函數,而await
只能在這個函數裏面使用。await
表示在這裏等待await
後面的操作執行完畢,再執行下一句代碼。await
後面緊跟着的最好是一個耗時的操作或者是一個異步操作(方法)。
深入async/await
async返回值
async
用於定義一個異步函數,該函數返回一個Promise
。
如果async
函數返回的是一個同步的值,這個值將被包裝成一個理解resolve
的Promise
,等同於return Promise.resolve(value)
。
await
用於一個異步操作之前,表示要“等待”這個異步操作的返回值。await
也可以用於一個同步的值。
function getSomething() {
return "something";
}
async function testAsync() {
return Promise.resolve("hello async");
}
async function test() {
const v1 = await getSomething();
const v2 = await testAsync();
console.log(v1, v2);
}
test(); // something hello async
這裏就會說明一個問題了,爲什麼await關鍵詞只能在async函數中用?
await
操作符等的是一個返回的結果,那麼如果是同步的情況,那就直接返回了。
那如果是異步的情況呢,異步的情況下,await
會阻塞整一個流程,直到結果返回之後,纔會繼續下面的代碼。
阻塞代碼那會很難受,所以await
關鍵詞就只能在async
函數中使用了。
//返回一個同步的值
let sayHi = async function sayHi(){
let hi = await 'hello world';
return hi; //等同於return Promise.resolve(hi);
}
sayHi().then(result=> {
console.log(result);
});
上面這個例子返回是一個同步的值,字符串'hello world'
,sayHi()
是一個async函數,返回值被包裝成一個Promise
,可以調用then()
方法獲取返回值。
對於一個同步的值,可以使用await
,也可以不使用await
。效果效果是一樣的。具體用不用,看情況。
錯誤處理
我們都知道promise
並不是只有一種resolve
,還有一種reject
(錯誤處理)的情況。而await
只會等待一個結果,那麼發生錯誤了該怎麼處理呢?
我們可直接在async
函數中拋出一個異常,由於返回的是一個Promise
,因此,這個異常可以調用返回Promise
的catch()
方法捕捉到。
let sayHi = async function sayHi(){
throw new Error('出錯了');
}
sayHi().then(result=> {
console.log(result);
}).catch(err=> {
console.log(err.message); //出錯了
});
async/await和promise的區別
Promise
最大的好處是在異步執行的流程中,把執行代碼和處理結果的代碼清晰地分離了,但是如果業務場景是這樣呢?我們先調起promise1,然後根據返回值,調用promise2,之後再根據這兩個Promises得值,調取promise3。代碼如下:
const req = () => {
return promise1()
.then(value1 => {
// do something
return promise2(value1)
.then(value2 => {
// do something
return promise3(value1, value2)
})
})
}
再好的解決方案,在項目結構複雜以後總會出現問題,promise
正是如此,代碼雖然條理清晰,但是也顯得臃腫。
而相同的業務場景,使用async/await
確實十分的爽~
const req = async () => {
const value1 = await promise1()
const value2 = await promise2(value1)
return promise3(value1, value2)
}
學習async/await
還是很有必要的,可能偶爾在什麼地方用到,就來了一波騷操作。