当前位置: 首页 > article >正文

JavaScript异步编程:async、await的使用

async 和 await 是在 ECMAScript 2017 (ES7) 中引入的特性,用于处理异步操作。它们允许你以一种更加简洁和同步的方式来编写异步代码。

async 函数表示它会返回一个 Promise,而 await 关键字用于等待一个 Promise 解决。

关于 promise 的详细介绍,请点击浏:《ECMAScript6语法:Promise》

1、使用 async 修饰符函数

 async 是一个函数修饰符,用于声明一个函数是异步的。调用 async 函数时,该函数会立即返回一个 Promise 对象,即使函数体内部没有显式返回 Promise,JavaScript 也会自动将函数的结果封装成 Promise 对象。

语法格式:

//使用 async 关键字修饰函数,被修饰的函数,一定返回 Promise 对象
async function asyncFun() {
    return "pan_junbiao的博客";
}

//上述代码,相当于
async function asyncFun() {
    return new Promise((resolve, reject) => {
        resolve("pan_junbiao的博客");
    });
}

//打印函数结果:一个 Promise 对象
console.log(asyncFun());

//打印 Promise 对象的值:pan_junbiao的博客
asyncFun().then((result) => console.log(result));

2、使用 await 等待 Promise 结果

await‌ 必须在 async 函数内部使用。它可以让异步代码像同步代码一样执行,等待 Promise 对象解决后再继续执行下一步。await 后面可以接非 Promise 对象(返回该对象的结果)或者 Promise 对象(返回对应的值)。

语法格式:

// 1、使用 async 关键字修饰函数,被修饰的函数,一定返回 Promise 对象
async function asyncFun() {
    return new Promise((resolve, reject) => {
        //使用定时器,模拟异步效果,等待3秒后,返回结果
        setTimeout(() => { resolve("pan_junbiao的博客") }, 3000);
    });
}

// 2、使用 await 等待 Promise 执行完成后返回结果(注意:await‌ 必须在 async 函数内部使用)
async function getUserName() {
    let userName = await asyncFun();
    console.log("用户名称:", userName);
}

// 3、执行方法
getUserName();

执行结果:

3、什么是回调地狱

回调地狱是指在异步编程中,由于多个回调函数嵌套调用,导致代码可读性差、难以维护的情况‌。

在 JavaScript 中,回调函数常用于处理异步任务,如 AJAX 请求、Promise 执行和事件绑定等。一旦操作完成,JavaScript 引擎会调用回调函数来处理结果。然而,当多个异步操作连续进行,且每个操作都需要在上一个操作完成后才能执行时,就会出现回调地狱。

回调地狱的问题包括:可读性差,错误处理困难,代码维护困难,以及控制流困难。为了解决这些问题,开发者采用了多种方法,包括使用 Promises、Async/Await、Generators 以及功能编程库等。这些方法使得异步代码的编写更加简洁、易读和易于维护‌。

4、Vue项目实例

【实例】创建 Vue 项目,使用 async、await函数,实现首先获取用户信息,然后根据用户信息中的部门编号,获取部门信息。

(1)创建 Vue 项目

创建 Vue 项目和使用 axios 二次封装实现 Ajax 请求功能,详情请点击浏览文章:《Vue使用axios二次封装、解决跨域问题》

(2)创建 UserInfo.vue 组件

<template>
    <h3>基本信息</h3>
    <p>用户名称:{{ userInfo.userName }}</p>
    <p>博客信息:{{ userInfo.blogName }}</p>
    <p>博客地址:{{ userInfo.blogUrl }}</p>
    <h3>部门信息</h3>
    <p>部门编号:{{ userInfo.departmentCode }}</p>
    <p>部门名称:{{ userInfo.departmentName }}</p>
    <button @click="getUser(1)">查询用户</button>
</template>

<script setup>
import { getUserInfo } from '@/api/UserApi.js';
import { getDepartmentInfo } from '@/api/DepartmentApi.js';
import { ref } from 'vue';

// 用户信息:使用 ref 定义一个响应式对象
let userInfo = ref({});

// 常规写法:形成“回调地狱”,代码可读性差,维护困难
// function getUser(userId) {
//     // 1、获取用户信息
//     getUserInfo(userId).then(
//         function (result) {
//             userInfo.value = result;

//             //2、获取部门信息
//             getDepartmentInfo(userInfo.value.departmentCode).then(
//                 function (department) {
//                     userInfo.value.departmentCode = department.departmentCode;
//                     userInfo.value.departmentName = department.departmentName;
//                 }
//             );
//         }
//     );
// }

// 使用 async、await 优化写法,代码简洁,易于维护
async function getUser(userId) {
    // 1、获取用户信息
    let userResult = await getUserInfo(userId);
    userInfo.value = userResult;

    //2、获取部门信息
    let department = await getDepartmentInfo(userInfo.value.departmentCode);
    userInfo.value.departmentCode = department.departmentCode;
    userInfo.value.departmentName = department.departmentName;
}

</script>

执行结果:


http://www.kler.cn/a/325440.html

相关文章:

  • SQL面试题——抖音SQL面试题 最大在线用户数
  • 串口DMA接收不定长数据
  • 机器学习-36-对ML的思考之机器学习研究的初衷及科学研究的期望
  • Python 使用Django进行单元测试unittest
  • 【nginx】client timed out和send_timeout的大小设置
  • Vue学习记录03
  • Bug:ThreadPoolTaskScheduler搭配CronTask完成定时任务,关闭scheduler后CronTask任务仍然执行?
  • ROS学习笔记(二):鱼香ROS — 超便捷的一键安装/配置/换源指令(Ubuntu/ROS/ROS2/IDE等)
  • android和ios双端应用性能的测试工具
  • springBoot --> 学习笔记
  • 锐捷—NAT地址映射+IPsec隧道
  • 使用openpyxl轻松操控Excel文件
  • C++学习笔记(48)
  • grafana加载缓慢解决方案
  • 初学playbook,从一个简单的示例开始。
  • Vue前端浏览器指纹获取:数字世界的身份密码
  • linux常见指令与权限【第四课】
  • C语言基本语法————基本数据类型、变量与常量
  • HDFS组件相关问题-持续更新
  • Growthly Quest 增长工具:助力 Web3 项目实现数据驱动的增长
  • RTE 大会报名丨AI 时代新基建:云边端架构和 AI Infra ,RTE2024 技术专场第二弹!
  • 【在Linux世界中追寻伟大的One Piece】进程间通信
  • 在Windows on Arm上使用Electron构建桌面应用
  • Rust和Go谁会更胜一筹
  • Day28笔记-Python自动化操作Word
  • Redis结合Caffeine实现二级缓存:提高应用程序性能