JavaScript入门⑧|Promise与async_await,彻底搞懂异步编程
·
author: 专注前端开发,分享JavaScript干货
title: JavaScript入门⑧|Promise与async_await,彻底搞懂异步编程
update: 2026-04-28
tags: JavaScript,Promise,async,await,异步,回调地狱,then,catch,前端入门
作者:专注前端开发,分享JavaScript干货
更新时间:2026年4月
适合人群:掌握JS基础,想彻底理解异步编程的同学
前言:同步与异步
JavaScript是单线程的,同步代码会阻塞后面代码的执行。
异步:不等待耗时操作完成,先往下执行,等操作好了再通知你。
// 同步:排队执行
console.log("1");
console.log("2");
console.log("3");
// 异步:不等结果,先往下走
console.log("1");
setTimeout(() => console.log("3"), 1000);
console.log("2"); // 这行先执行
// 输出顺序:1 → 2 → 3
一、回调函数的困境
// 老式回调:多层嵌套后变成"回调地狱"
getUser(userId, function(user) {
getOrders(user.id, function(orders) {
getOrderDetails(orders[0].id, function(details) {
getProduct(details.productId, function(product) {
console.log(product);
});
});
});
});
问题:嵌套太深、错误处理困难、代码难维护。
二、Promise 基础
2.1 创建Promise
// Promise有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true;
if (success) {
resolve("操作成功!"); // 成功时调用resolve
} else {
reject(new Error("操作失败!")); // 失败时调用reject
}
}, 1000);
});
console.log(promise); // Promise { <pending> }
2.2 then / catch / finally
promise
.then(result => {
console.log(result); // "操作成功!"
return "第二次成功";
})
.then(result => {
console.log(result); // "第二次成功"
})
.catch(error => {
console.error(error.message); // 处理错误
})
.finally(() => {
console.log("无论成功失败都会执行"); // 做清理工作
});
2.3 Promise链式调用
// 用Promise改写回调地狱,扁平化
getUser(userId)
.then(user => getOrders(user.id))
.then(orders => getOrderDetails(orders[0].id))
.then(details => getProduct(details.productId))
.then(product => console.log(product))
.catch(error => console.error(error.message));
三、Promise静态方法
3.1 Promise.all(全部成功才成功)
// 同时发送多个请求,等全部完成
const promise1 = fetchUser();
const promise2 = fetchPosts();
const promise3 = fetchComments();
Promise.all([promise1, promise2, promise3])
.then(([user, posts, comments]) => {
console.log("用户:", user);
console.log("帖子:", posts);
console.log("评论:", comments);
})
.catch(error => {
console.error("某个请求失败了:", error);
});
3.2 Promise.allSettled(全部完成,无论成功失败)
// 想知道每个请求的结果,不管成功还是失败
Promise.allSettled([
fetchUser(),
fetchPosts(),
fetchFailingRequest() // 这个会失败
]).then(results => {
results.forEach((result, index) => {
if (result.status === "fulfilled") {
console.log(`请求${index}成功:`, result.value);
} else {
console.log(`请求${index}失败:`, result.reason);
}
});
});
3.3 Promise.race(返回最快的那个)
// 哪个先完成就用哪个(常用于超时控制)
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error("超时!")), 5000)
);
const fetchPromise = fetch("https://api.example.com/data");
Promise.race([fetchPromise, timeoutPromise])
.then(data => console.log("获取成功:", data))
.catch(error => console.error("失败:", error.message));
3.4 Promise.any(返回第一个成功的)
// 多个接口,只要有一个成功就行
Promise.any([
fetch("https://api1.example.com"),
fetch("https://api2.example.com"),
fetch("https://api3.example.com")
]).then(result => console.log("最快的成功结果:", result));
四、async / await(同步写法写异步)
4.1 基本用法
// async函数自动返回Promise
async function fetchData() {
// await暂停函数执行,等待Promise解决
const result = await someAsyncFunction();
console.log(result);
return result;
}
// 调用
fetchData().then(result => console.log("最终结果", result));
4.2 实战:顺序请求与并行请求
// 模拟异步函数
const delay = (ms, value) =>
new Promise(resolve => setTimeout(() => resolve(value), ms));
// 顺序执行(串行)
async function sequential() {
const start = Date.now();
const r1 = await delay(1000, "结果1");
const r2 = await delay(1000, "结果2");
const r3 = await delay(1000, "结果3");
const elapsed = Date.now() - start;
console.log(`顺序执行耗时:${elapsed}ms`); // ~3000ms
return [r1, r2, r3];
}
// 并行执行(Promise.all + await)
async function parallel() {
const start = Date.now();
const promises = [
delay(1000, "结果1"),
delay(1000, "结果2"),
delay(1000, "结果3")
];
const results = await Promise.all(promises);
const elapsed = Date.now() - start;
console.log(`并行执行耗时:${elapsed}ms`); // ~1000ms
return results;
}
async function main() {
console.log("--- 顺序 ---");
await sequential();
console.log("--- 并行 ---");
await parallel();
}
main();
4.3 错误处理
async function fetchUserData(id) {
try {
// 可能失败的代码
const user = await fetchUser(id);
const posts = await fetchPosts(user.id);
// 手动的错误检查
if (!user) {
throw new Error("用户不存在");
}
return { user, posts };
} catch (error) {
console.error("获取数据失败:", error.message);
return null; // 返回默认值
} finally {
console.log("请求完成,无论成功失败");
}
}
// 并行请求的错误处理
async function fetchMultiple() {
try {
const [user, posts, comments] = await Promise.all([
fetchUser(1),
fetchPosts(1),
fetchComments(1)
]);
return { user, posts, comments };
} catch (error) {
console.error("某个请求失败了:", error.message);
throw error; // 或者重新抛出
}
}
五、知识卡
| 方法 | 说明 |
|---|---|
new Promise() |
创建Promise |
.then() |
Promise成功后执行 |
.catch() |
Promise失败后执行 |
.finally() |
无论成功失败都执行 |
Promise.all() |
全部成功才成功 |
Promise.allSettled() |
全部完成,保留所有结果 |
Promise.race() |
返回最快的 |
Promise.any() |
返回第一个成功的 |
async |
声明异步函数 |
await |
等待Promise解决 |
六、课后作业
- 用
Promise封装一个delay函数,模拟延迟 - 实现一个函数,同时请求3个接口,返回所有成功的结果,忽略失败的
- 用
async/await重写一个多层嵌套的回调函数
有问题欢迎评论区留言,大家一起讨论!
标签:JavaScript | Promise | async | await | 异步编程 | 回调地狱 | then | catch
更多推荐


所有评论(0)