解锁 JavaScript 异步编程:Promise 链式操作、async/await 与 Promise.all 深度剖析
1.引言
在 JavaScript 的世界里,异步编程是一个核心且关键的概念。随着 Web 应用的复杂度不断提升,处理多个异步操作的需求也日益增长。传统的回调函数方式容易陷入 “回调地狱”,让代码的可读性和可维护性大打折扣。而 Promise 的出现为异步编程带来了新的曙光,后续又衍生出了 async/await 语法糖以及 Promise.all 等实用方法。今天,我们就来深入探讨这三者在异步编程中的应用和区别。
2.Promise 链式操作:异步操作的有序舞蹈
基本原理
Promise 是一个表示异步操作最终完成或失败及其结果的对象。它有三种状态:进行中(pending)、已成功(fulfilled)和已失败(rejected)。Promise 链式操作通过 .then() 方法来依次处理异步操作的结果,每个 .then() 方法都会返回一个新的 Promise 对象,从而可以继续链式调用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
目标:使用 Promise 链式调用,解决回调函数地狱问题
做法:每个 Promise 对象中管理一个异步任务,用 then 返回 Promise 对象,串联起来
目标:把回调函数嵌套代码,改成Promise链式调用结构
需求:获取默认第一个省,第一个市,第一个地区并展示在下拉菜单中
-->
<form>
<span>省份:</span>
<select>
<option class="province"></option>
</select>
<span>城市:</span>
<select>
<option class="city"></option>
</select>
<span>地区:</span>
<select>
<option class="area"></option>
</select>
</form>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
//全局变量
let pname = ''
//1.获取省份Promise对象
axios({
url: 'https://hmajax.itheima.net/api/province'
}).then(result => {
console.log(result.data.list);
pname = result.data.list[0]
document.querySelector('.province').innerHTML = pname
//2.得到-获取城市Promise对象
return axios({
url: 'https://hmajax.itheima.net/api/city',
params: {
pname//pname:pname
}
})
}).then(result => {
let cname = result.data.list[0]
console.log(result.data.list);
document.querySelector('.city').innerHTML = cname
//3.得到-获取地区Promise对象
return axios({
url: 'https://hmajax.itheima.net/api/area',
params: {
pname,
cname
}
})
}).then(result => {
console.log(result);
document.querySelector('.area').innerHTML = result.data.list[0]
})
</script>
</body>
</html>
优缺点分析
优点是可以将多个异步操作按顺序依次执行,避免了回调函数的嵌套,一定程度上提高了代码的可读性。缺点是当异步操作较多时,链式调用会变得冗长,并且错误处理集中在 .catch() 方法中,难以精准定位错误发生的位置
3.async/await:异步代码的同步之美
基本原理
async/await 是 ES2017 引入的语法糖,建立在 Promise 之上。async 用于定义一个异步函数,该函数总是返回一个 Promise。await 只能在 async 函数内部使用,它会暂停 async 函数的执行,直到等待的 Promise 被解决,并返回其结果。