async函数
什么是async函数?
async函数
是使用async
关键字声明的函数。
mdn文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function
async函数
有以下两个特点:
- 函数的返回值为
Promise
对象 -
Promise
对象的结果由async函数
执行的返回值决定
为什么要用async函数?
async
和await
关键字让我们可以用一种更简洁的方式写出基于Promise
的异步行为,而无需刻意地链式调用promise
。
async函数怎么使用?
使用示例:
<script>
// async 返回一个Promise对象。
async function main() {
// 1. 如果返回值是一个非Promise类型的数据,那返回的是一个成功的Promise对象,结果是返回的数据。
return 5555;
// 2. 如果返回的是一个Promise对象,那么这个对象的状态和结果,就是这个函数的状态和结果
// return new Promise((resolve, reject) => {
// // resolve('OK');
// // reject('ERROR');
// // throw '出错了'
// })
// 3. 抛出异常,返回的是一个失败的Promise对象,结果为throw后面抛出的信息。
// throw 'error';
}
let result = main();
console.log(result);
</script>
await表达式
什么是await表达式?
await
操作符用于等待一个Promise
对象。它只能在异步函数 async function
中使用。
语法:
[返回值] = await 表达式;
表达式:一个Promise
对象或者任何要等待的值。
返回值:返回Promise
对象的处理结果。如果等待的不是Promise
对象,则返回该值本身。
mdn文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await
为什么要用await表达式?
async
和await
关键字让我们可以用一种更简洁的方式写出基于Promise
的异步行为,而无需刻意地链式调用promise
。
await表达式怎么使用?
使用示例:
<script>
async function main() {
let p = new Promise((resolve, reject) => {
resolve('OK');
// reject('ERROR') // 配合下面的案例3使用。案例1会直接报错,因为没有异常处理,await需要手动处理异常。案例2,能够得到结果,并且抛出异常。
})
// 1. await 右侧为Promise对象的情况,返回值为Promise对象成功的结果值。
// let result = await p;
// console.log(result); // OK
// 2. 右侧为其他类型的数据,那么返回值为 await 后面的那个值
let result = await 20;
console.log(result) // 20
// 3. 右侧的Promise对象为失败的状态,则会抛出异常,此时用try...catch 捕获异常,可以在catch中拿到失败的结果
// try {
// let result = await p;
// } catch(e) {
// console.log(e);
// }
}
main();
</script>
注意:
-
await
必须写在async函数
中,但async函数
中可以没有await
。 - 如果
await
的Promise
失败了,就会抛出异常,需要通过try...catch
捕获处理。
案例1:
async与await结合发送ajax请求获取段子。
html中简单的放一个按钮就行
<button>点击获取段子</button>
js代码:
<script>
// 封装AJAX请求
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(简单用了下Node.js
,可以忽略这个案例):
使用Node.js
读取三个文件(任意选三个文件)中的数据并进行拼接,然后在控制台输出。
代码:
const fs = require('fs');
const util = require('util');
// 回调函数方式实现
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实现
const mineReadFile = util.promisify(fs.readFile);
async function main() {
// 如果出错
try {
// 读取文件内容
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);
}
}