在 JavaScript 中,处理异步操作一直是开发者们面临的挑战之一。传统的回调函数方式往往导致代码难以维护、可读性差、易产生回调地狱等问题。为了解决这些问题,出现了 Promise 和 Async/Await 这两种处理异步操作的方式。
一、异步产生问题示例
当我们异步获取一个数据进行同步展示时,数据的获取是有延迟的如下:
onMounted(() => {echarsAll(n.value)init()//data1为echarsAll(n.value)方法获取进行赋值的console.log(data1)
})
控制台打印:
当我们再次添加定时器进行延迟打印时:
onMounted(() => {echarsAll(n.value)//init1()init()setTimeout(() => {console.log(data1)}, 1000)
})
控制台打印,能够获取到结果:
二、 Promise 、Async/Await简介
当我们使用异步获取数据如何像同步一样进行一个展示呢?这就需要使用 Promise 或 Async/Await 来实现类似同步的数据获取方式。
1、使用 Promise 获取异步数据
const getYesterday = () => {return new Promise<void>(async (resolve, reject) => {try {const res = await useFacYesterdayApi()dataForm.yesterdayout = res.data[1]dataForm.yesterdayin = res.data[2]resolve()} catch (error) {// 处理错误reject(error)}})
}
(1)promise的使用步骤
-
调用
Promise
构造函数并传入一个函数作为参数,该函数接收两个参数:resolve
和reject
。 -
在函数体内,我们可以编写异步任务的代码,并通过
resolve
函数或reject
函数来处理任务的结果。
(2)promise的执行原理
Promise 是基于事件循环机制的。在创建 Promise 对象时,会立即执行传入的异步任务代码,并将其封装在一个函数中。
- 异步任务代码中通常会调用
resolve
函数或reject
函数来处理任务的结果。 - 当异步任务成功完成时,会调用
resolve
函数; - 当异步任务失败时,会调用
reject
函数。
可以通过链式调用 then
方法来处理多个异步任务的结果。每次调用 then
方法都会返回一个新的 Promise 对象,因此可以在其后继续调用 then
方法。
2、使用 Async/Await 获取异步数据
const getYesterday = async () => {try {const res = await useFacYesterdayApi()dataForm.yesterdayout = res.data[1]dataForm.yesterdayin = res.data[2]} catch (error) {// 处理错误console.log(dataForm.yesterdayin)}
}
Async/Await 是 ES2017 引入的语法糖,基于 Promise 的基础上提供了更简洁、直观的方式来处理异步操作。使用 Async/Await 可以让异步代码更像同步代码,提升代码的可读性和可维护性。通过在函数前加上 async
关键字,我们定义了一个异步函数,并在其中使用 await
关键字等待 Promise 对象的结果。
(1)Async/Await的使用步骤
- 使用
async
关键字来定义一个异步函数。异步函数可以包含await
关键字,用于等待 Promise 对象的解决。 - 在异步函数中,使用
await
关键字等待一个返回 Promise 对象的表达式,再继续执行后续代码。
(2) Async/Await的执行原理
async、await看起来更加简洁,使得异步代码看起来像同步代码,只有await的代码执行完毕后才会执行下面的代码; async/await基于Promise实现,相当于Promise的升级版,不能用于普通的回调函数;