目录
[(2)Async 函数](#(2)Async 函数)
[(3)Await 表达式](#(3)Await 表达式)
[(4)Async/Await 的优缺点](#(4)Async/Await 的优缺点)
[(2)使用 await 等待 Promise](#(2)使用 await 等待 Promise)
本文主要讲解JavaScript异步编程中Async/Await的理解及基本用法等。
1.对Async/Await的了解
(1)介绍
Async/Await
是 JavaScript ES8引入的用于处理异步操作的语法糖,它建立在 Promises 的基础上的。使用 async/await
,可以以几乎同步的方式编写异步代码,极大地简化了复杂异步逻辑的处理。
(2)Async 函数
async
关键字用于声明一个异步函数,这样的函数会隐式地返回一个 Promise。
可以在函数内部使用 await
表达式来等待异步操作的完成。
如果没有显式地返回一个值,async
函数将返回一个解析为 undefined
的 Promise。
(3)Await 表达式
await
关键字只能在 async
函数内部使用。
await
等待一个 Promise,并暂停 async
函数的执行,直到 Promise 被解决或拒绝,然后返回解决的值或抛出拒绝的错误。
await
可以使异步代码看起来和同步代码一样,但它不会阻塞整个程序的执行。
(4)Async/Await 的优缺点
优点
代码清晰 :async/await
使得异步代码更加直观和易于理解。
错误处理 :与 .then().catch()
链相比,try/catch
语句可以更容易地捕获和处理异步操作中的错误。
条件语句和循环中的使用 :在 async
函数中,可以像处理同步操作一样,在条件语句和循环中使用 await
。
减少回调地狱 :通过避免多层嵌套的回调函数,async/await
使得代码更加简洁和可维护。
缺点
性能考虑 :虽然 async/await
本身不会阻塞整个 JavaScript 运行时,但过多的等待,特别是长时间运行的异步操作可能会影响应用的性能和响应性。
调试复杂性 :由于 async/await
使得异步代码看起来像是同步的,可能会增加调试时的复杂性,特别是当多个异步操作并行或相互依赖时。
兼容性 :虽然现代浏览器和 Node.js 版本都支持 async/await
,但在一些旧环境中可能需要使用 Babel 等转译工具来支持。
2.基本用法
(1)声明异步函数
使用 async
关键字来声明一个异步函数。
async function fetchData() {
// 函数体
}
(2)使用 await 等待 Promise
在 async
函数内部,可以使用 await
关键字来等待一个 Promise 完成。当 await
表达式后面的 Promise 被解决时,await
表达式的结果就是 Promise 解决的值。
function testAsy(x){
return new Promise(resolve=>{
setTimeout(()=>{
resolve(x)
},3000)
})
}
async function testAwt(){
// await先暂停当前async,等待返回值
let result = await testAsy("async");
console.log(result);
}
testAwt();
(3)错误处理
当 await
等待的 Promise 被拒绝时,它会抛出一个错误。这个错误可以被 try/catch
语句捕获。
async function fn(){
try {
let a=await Promise.reject('error')
}catch(error){
console.log(error);
}
}
3.Async返回什么
async函数返回的是一个Promise对象,是Promise的resolve值。最外层不能用await获取其返回值,所以用then()链来处理这个Promise对象。如果async函数没有返回值,则会返回Promise.resolve(undefined))
async function test(){
return "Happy"
}
let result = test();
console.log(result);
result.then(value=>{
console.log(value);
})
4.Await的等待
await
关键字主要用于等待一个异步操作的完成。尽管语法上 await
后面跟的是一个表达式,但这个表达式的计算结果可以是 Promise
对象,也可以是其他非 Promise
类型的值。
当 await
遇到一个 Promise
对象时,它会暂停当前 async
函数的执行,直到该 Promise
被解决,并等待其返回值。
如果 await
后面的表达式直接返回一个非 Promise
值(如一个普通函数的返回值或字面量),await
表达式的运算结果就是它等到的东西。
function getSomething(){
return "Happy Day!!!"
}
async function test3(){
return Promise.resolve("~~~~");
}
async function test2(){
let v1 = await getSomething();
let v2 = await test3();
console.log(v1,v2);
}
test2();
5.async\await的优势及案例
async\await的优势:处理由多个Promise组成的then链时,优势就出来了。 Promise通过then链解决了多层回调问题,async\awiat进一步优化了,代码更加直观和易于理解。
假设我们有一个用户注册流程,它分为以下几个步骤:
验证用户名是否已存在;
验证用户密码强度;
创建用户账户;
发送欢迎邮件。
// 验证用户名是否已存在
function userExists(username) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (username === 'existingUser') {
reject(new Error('Username already exists'));
} else {
resolve(true);
}
}, 1000);
});
}
// 验证用户密码强度
function securPassword(password) {
return new Promise((resolve, reject) => {
// 简单的密码强度验证
if (password.length < 6) {
reject(new Error('Password must be at least 6 characters long'));
} else {
resolve(true);
}
});
}
// 创建用户账户
function createUser(username, password) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`User ${username} created with password`);
}, 1000);
});
}
// 发送邮箱
function sendEmail(username) {
return new Promise((resolve, reject) => {
// 模拟发送邮件
setTimeout(() => {
console.log(`Welcome email sent to ${username}`);
resolve(`Email sent to ${username}`);
}, 500);
});
}
使用Promises链来处理流程
userExists('newUser')
.then(exists => {
if (!exists) {
throw new Error('Unexpected state: username should not exist here');
}
return securPassword('securePassword123');
})
.then(valid => {
if (valid) {
return createUser('newUser', 'securePassword123');
}
throw new Error('Invalid password');
})
.then(result => {
return sendEmail('newUser');
})
.then(emailResult => {
console.log(emailResult);
})
.catch(error => {
console.error(error.message);
});
使用async\await
async function registerUser(username, password) {
try {
await userExists(username);
await securPassword(password);
const accountCreationResult = await createUser(username, password);
const emailResult = await sendEmail(username);
console.log(emailResult);
} catch (error) {
console.error(error.message);
}
}
6.总结
Async/Await 是 JavaScript 中处理异步操作的强大工具,它允许我们以同步的方式编写异步代码,极大地提高了代码的可读性和可维护性。通过 async 声明异步函数,并在函数体内使用 await 等待 Promise 解决,能够以更直观、更简洁的方式处理异步流程,避免了传统回调地狱的复杂性。