前端小白也能看懂的 Promise 原理与使用教程(附 async/await 升级指南)
在前端开发中,处理异步任务是家常便饭,比如:
- 等待
setTimeout
执行 - 从接口中获取数据(
fetch
) - 文件读取(如
readFile
)
这些操作都不是立即完成的。如果我们不加控制,这些"慢动作"就会打乱我们写代码的顺序,导致代码难以理解和维护。
于是,ES6 引入了一个神器 ------ Promise
,它的出现,就是为了"控制异步任务的执行流程"。
📌 什么是异步?为什么需要 Promise?
我们先看一个例子:
javascript
console.log("开始");
setTimeout(() => {
console.log("中间的异步任务");
}, 1000);
console.log("结束");
你可能以为打印顺序是:
开始
中间的异步任务
结束
但实际结果是:
开始
结束
中间的异步任务
为什么?因为 setTimeout
是异步任务,它会被放到任务队列中,等主线程(同步任务)跑完了,再回来执行。
🧠 问题来了:
- 代码写的顺序和执行的顺序不一样 ❌
- 代码越来越多后,可读性差、维护困难 ❌
所以,我们需要一个机制,让异步执行变得更 「顺滑 」「可控」。
🎯 Promise 是什么?
你可以把 Promise 理解成"一个装着未来结果的饼干罐子"。
javascript
const p = new Promise((resolve, reject) => {
// 异步任务,比如读取文件、发请求等
setTimeout(() => {
// 异步成功
resolve("数据加载成功!");
}, 1000);
});
这个 Promise
实例就代表一个未来某个时间才会完成的操作。
resolve()
表示成功的回调reject()
表示失败的回调- 然后你就可以用
.then()
来注册这个成功后的回调函数
javascript
p.then((result) => {
console.log(result); // 输出:数据加载成功!
});
🧩 Promise 的执行流程解析
- 你创建了一个
Promise
实例 - 把耗时的异步任务塞进
new Promise(fn)
的函数里 - 当任务完成,就调用
resolve()
,告诉它:"喂,我好了!" then()
里面写的逻辑就会被执行- 整个流程由你掌控,异步的"顺序"终于变得清晰!
📘 小结一下 Promise 的核心概念
概念 | 说明 |
---|---|
new Promise() |
创建一个 Promise 实例,表示一个未来要完成的任务 |
resolve() |
成功时调用,用来触发 .then() |
reject() |
失败时调用,用来触发 .catch() |
.then() |
注册任务完成后的操作 |
.catch() |
注册任务失败时的处理 |
.finally() |
无论成功或失败,最后都会执行 |
🚀 Promise 的升级版本:async / await
虽然 Promise 已经很好用了,但有时候多个 .then().then()
会写得很复杂。这时候,ES8 的 async/await 就更香了!
来看一下对比 👇
用 Promise:
scss
getUserInfo().then((user) => {
return getPostsByUser(user.id);
}).then((posts) => {
console.log(posts);
});
用 async/await:
scss
async function loadData() {
const user = await getUserInfo();
const posts = await getPostsByUser(user.id);
console.log(posts);
}
loadData();
是不是像写同步代码一样直观?😍
✅ 总结
技术点 | 解决的问题 |
---|---|
Promise |
解决异步流程混乱,代码顺序与执行顺序不一致的问题 |
resolve/reject |
手动触发后续操作 |
.then() |
注册"任务完成后"的操作 |
async/await |
让异步代码像同步一样好写,提升代码可读性 |
🛠 练习题(推荐尝试)
javascript
// 尝试写一个返回 Promise 的函数,并用 async/await 调用它
function delay(ms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`延迟了 ${ms} 毫秒`);
}, ms);
});
}
async function run() {
const result = await delay(1000);
console.log(result); // 延迟了 1000 毫秒
}
run();
🧡 写在最后
如果你刚入门前端,Promise 是你必须掌握的一道坎。它不仅是 JS 异步的基础,也是进入框架(比如 Vue、React)前的重要跳板。
继续探索、不断实践,Promise 和 async/await 会成为你开发路上最好的帮手!