JavaScript异步编程的Async/Await

目录

1.对Async/Await的了解

(1)介绍

[(2)Async 函数](#(2)Async 函数)

[(3)Await 表达式](#(3)Await 表达式)

[(4)Async/Await 的优缺点](#(4)Async/Await 的优缺点)

2.基本用法

(1)声明异步函数

[(2)使用 await 等待 Promise](#(2)使用 await 等待 Promise)

(3)错误处理

3.Async返回什么

​编辑

​编辑

4.Await的等待

5.async\await的优势及案例

6.总结


本文主要讲解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 解决,能够以更直观、更简洁的方式处理异步流程,避免了传统回调地狱的复杂性。

相关推荐
神仙别闹7 分钟前
基于C#和Sql Server 2008实现的(WinForm)订单生成系统
开发语言·c#
XINGTECODE8 分钟前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
前端百草阁23 分钟前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜23 分钟前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
Backstroke fish24 分钟前
Token刷新机制
前端·javascript·vue.js·typescript·vue
zwjapple25 分钟前
typescript里面正则的使用
开发语言·javascript·正则表达式
小五Five26 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
临枫54126 分钟前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
酷酷的威朗普27 分钟前
医院绩效考核系统
javascript·css·vue.js·typescript·node.js·echarts·html5
前端每日三省28 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript