async函數(shù)
什么是async函數(shù)?
async函數(shù)
是使用async
關(guān)鍵字聲明的函數(shù)蓝谨。
mdn文檔:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function
async函數(shù)
有以下兩個(gè)特點(diǎn):
- 函數(shù)的返回值為
Promise
對(duì)象 -
Promise
對(duì)象的結(jié)果由async函數(shù)
執(zhí)行的返回值決定
為什么要用async函數(shù)灌具?
async
和await
關(guān)鍵字讓我們可以用一種更簡(jiǎn)潔的方式寫出基于Promise
的異步行為,而無需刻意地鏈?zhǔn)秸{(diào)用promise
譬巫。
async函數(shù)怎么使用咖楣?
使用示例:
<script>
// async 返回一個(gè)Promise對(duì)象。
async function main() {
// 1. 如果返回值是一個(gè)非Promise類型的數(shù)據(jù)芦昔,那返回的是一個(gè)成功的Promise對(duì)象诱贿,結(jié)果是返回的數(shù)據(jù)。
return 5555;
// 2. 如果返回的是一個(gè)Promise對(duì)象,那么這個(gè)對(duì)象的狀態(tài)和結(jié)果珠十,就是這個(gè)函數(shù)的狀態(tài)和結(jié)果
// return new Promise((resolve, reject) => {
// // resolve('OK');
// // reject('ERROR');
// // throw '出錯(cuò)了'
// })
// 3. 拋出異常料扰,返回的是一個(gè)失敗的Promise對(duì)象,結(jié)果為throw后面拋出的信息焙蹭。
// throw 'error';
}
let result = main();
console.log(result);
</script>
await表達(dá)式
什么是await表達(dá)式晒杈?
await
操作符用于等待一個(gè)Promise
對(duì)象。它只能在異步函數(shù) async function
中使用孔厉。
語法:
[返回值] = await 表達(dá)式;
表達(dá)式:一個(gè)Promise
對(duì)象或者任何要等待的值拯钻。
返回值:返回Promise
對(duì)象的處理結(jié)果。如果等待的不是Promise
對(duì)象撰豺,則返回該值本身粪般。
mdn文檔:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await
為什么要用await表達(dá)式?
async
和await
關(guān)鍵字讓我們可以用一種更簡(jiǎn)潔的方式寫出基于Promise
的異步行為污桦,而無需刻意地鏈?zhǔn)秸{(diào)用promise
亩歹。
await表達(dá)式怎么使用?
使用示例:
<script>
async function main() {
let p = new Promise((resolve, reject) => {
resolve('OK');
// reject('ERROR') // 配合下面的案例3使用寡润。案例1會(huì)直接報(bào)錯(cuò)捆憎,因?yàn)闆]有異常處理舅柜,await需要手動(dòng)處理異常梭纹。案例2,能夠得到結(jié)果致份,并且拋出異常变抽。
})
// 1. await 右側(cè)為Promise對(duì)象的情況,返回值為Promise對(duì)象成功的結(jié)果值氮块。
// let result = await p;
// console.log(result); // OK
// 2. 右側(cè)為其他類型的數(shù)據(jù)绍载,那么返回值為 await 后面的那個(gè)值
let result = await 20;
console.log(result) // 20
// 3. 右側(cè)的Promise對(duì)象為失敗的狀態(tài),則會(huì)拋出異常滔蝉,此時(shí)用try...catch 捕獲異常击儡,可以在catch中拿到失敗的結(jié)果
// try {
// let result = await p;
// } catch(e) {
// console.log(e);
// }
}
main();
</script>
注意:
-
await
必須寫在async函數(shù)
中,但async函數(shù)
中可以沒有await
蝠引。 - 如果
await
的Promise
失敗了阳谍,就會(huì)拋出異常,需要通過try...catch
捕獲處理螃概。
案例1:
async與await結(jié)合發(fā)送ajax請(qǐng)求獲取段子矫夯。
html中簡(jiǎn)單的放一個(gè)按鈕就行
<button>點(diǎn)擊獲取段子</button>
js代碼:
<script>
// 封裝AJAX請(qǐng)求
function sendAJAX(url) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject(xhr.status);
}
}
}
})
}
// 段子接口地址:https://api.apiopen.top/getJoke
// 獲取元素
const btn = document.querySelector('button');
btn.addEventListener('click', async function() {
let result = await sendAJAX('https://api.apiopen.top/getJoke');
console.log(result);
})
</script>
案例2(簡(jiǎn)單用了下Node.js
,可以忽略這個(gè)案例):
使用Node.js
讀取三個(gè)文件(任意選三個(gè)文件)中的數(shù)據(jù)并進(jìn)行拼接吊洼,然后在控制臺(tái)輸出训貌。
代碼:
const fs = require('fs');
const util = require('util');
// 回調(diào)函數(shù)方式實(shí)現(xiàn)
fs.readFile('./resource/1.txt', (err, data1) => {
if (err) throw err;
fs.readFile('./resource/content.txt', (err, data2) => {
if (err) throw err;
fs.readFile('./resource/2.txt', (err, data3) => {
if (err) throw err;
console.log(data1 + data2 + data3);
})
})
})
// 使用async和await實(shí)現(xiàn)
const mineReadFile = util.promisify(fs.readFile);
async function main() {
// 如果出錯(cuò)
try {
// 讀取文件內(nèi)容
let data1 = await mineReadFile('./resource/1x.txt');
let data2 = await mineReadFile('./resource/content.txt');
let data3 = await mineReadFile('./resource/2.txt');
console.log(data1 + data2 + data3);
} catch(e) {
console.log(e);
}
}