目录
- 一、 什么是 Promise?
- 二、 Promise 的基本用法
- 三、 Promise 的状态转换
- 四、 Promise 的链式调用
- 五、 Promise 的静态方法
- 六、 async/await (Promise 的语法糖)
- 总结
我的其他文章也讲解的比较有趣,如果喜欢博主的讲解方式,可以多多支持一下,感谢!
了解双亲委派机制请看: 双亲委派机制,你真的懂吗?
其他优质专栏: 【SpringBoot】【多线程】【Redis】【✨设计模式专栏(已完结)】…等
如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning
这篇文章来讲讲前端的知识Promise !
想象一下,你去餐厅点了一份外卖。你点了之后,餐厅会给你一个“承诺”:他们会给你送餐。
Promise 的本质: Promise 是一个代表异步操作最终完成(或失败)的对象。 它允许你以一种更清晰、更可控的方式处理异步操作,避免回调地狱。 ♀️➡️
// 创建一个 Promise
const myPromise = new Promise((resolve, reject) => {
// 这里写异步操作,比如发送一个网络请求,或者延迟一段时间
setTimeout(() => {
const success = true; // 假设操作成功
if (success) {
// 调用 resolve 表示操作成功
resolve("操作成功!"); // resolve 里面可以放成功的结果数据
} else {
// 调用 reject 表示操作失败
reject("操作失败!"); // reject 里面可以放失败的原因
}
}, 2000); // 延迟 2 秒
});
// 使用 Promise
myPromise
.then((result) => {
// 如果 Promise 成功了,会执行这里的代码
console.log("成功:", result);
})
.catch((error) => {
// 如果 Promise 失败了,会执行这里的代码
console.error("失败:", error);
})
.finally(() => {
// 无论 Promise 成功还是失败,都会执行这里的代码
console.log("操作完成!✅");
});
console.log("Promise 创建后立即执行的代码 ");
输出结果:
Promise 创建后立即执行的代码
// 2 秒后
成功: 操作成功!
操作完成!✅
代码解释:
new Promise((resolve, reject) => { ... })
: 创建一个新的 Promise 对象。
resolve
和 reject
是两个函数,它们由 JavaScript 引擎提供。resolve(value)
: 调用 resolve
表示 Promise 操作成功,value
是成功的结果。reject(reason)
: 调用 reject
表示 Promise 操作失败,reason
是失败的原因。setTimeout(() => { ... }, 2000)
: 模拟一个异步操作,这里是延迟 2 秒。.then((result) => { ... })
: then
方法用于处理 Promise 成功的情况。
result
: 是 resolve
函数传递过来的成功结果。.catch((error) => { ... })
: catch
方法用于处理 Promise 失败的情况。
error
: 是 reject
函数传递过来的失败原因。.finally(() => { ... })
: finally
方法用于处理 Promise 无论成功还是失败都需要执行的代码。new Promise
创建 Promise 对象,并立即执行 Promise 构造函数中的代码。console.log("Promise 创建后立即执行的代码");
会立即执行,因为 Promise 内部的异步操作是延迟执行的。setTimeout
中的代码执行,根据 success
的值调用 resolve
或 reject
。resolve
被调用,.then
中的代码会被执行。reject
被调用,.catch
中的代码会被执行。resolve
还是 reject
被调用,.finally
中的代码都会被执行。Promise 的状态只能从 Pending
转换为 Fulfilled
或 Rejected
,而且一旦转换,就不能再变回 Pending
状态。
Promise 最强大的特性之一就是可以进行链式调用,这使得处理多个异步操作变得非常方便。
function fetchData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
fetchData('https://jsonplaceholder.typicode.com/todos/1')
.then(data => {
console.log('Data received:', data);
return data.title; // 返回一个值,传递给下一个 then
})
.then(title => {
console.log('Title:', title);
return `The title is: ${title} `; // 返回一个值,传递给下一个 then
})
.then(formattedTitle => {
console.log('Formatted title:', formattedTitle);
})
.catch(error => {
console.error('Error fetching data:', error);
});
输出结果:
Data received: { userId: 1, id: 1, title: 'delectus aut autem', completed: false }
Title: delectus aut autem
Formatted title: The title is: The title is: delectus aut autem
链式调用的好处:
catch
捕获所有错误。 then
可以将处理后的数据传递给下一个 then
。 ➡️Promise 提供了一些静态方法,用于处理多个 Promise。
Promise.all(promises)
: 接收一个 Promise 数组,当所有 Promise 都成功时,返回一个包含所有结果的 Promise。 如果其中任何一个 Promise 失败,则立即返回一个 rejected 的 Promise。
const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'foo'));
const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'bar'));
Promise.all([promise1, promise2, promise3])
.then((values) => {
console.log(values); // 输出: [1, "foo", "bar"]
});
Promise.race(promises)
: 接收一个 Promise 数组,返回第一个 resolve 或 reject 的 Promise。 ♀️
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2])
.then((value) => {
console.log(value); // 输出: "two" (promise2 更快 resolve)
});
Promise.resolve(value)
: 返回一个 resolved 的 Promise,其值为 value
。 ✅
const resolvedPromise = Promise.resolve(42);
resolvedPromise.then((value) => {
console.log(value); // 输出: 42
});
Promise.reject(reason)
: 返回一个 rejected 的 Promise,其原因为 reason
。 ❌
const rejectedPromise = Promise.reject('Something went wrong!');
rejectedPromise.catch((reason) => {
console.error(reason); // 输出: "Something went wrong!"
});
async/await
是 ES2017 引入的语法糖,它使异步代码看起来更像同步代码,更容易阅读和编写。 async/await
实际上是基于 Promise 实现的。
async function fetchDataAndProcess(url) {
try {
const response = await fetch(url); // await 等待 Promise 完成
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json(); // await 等待 Promise 完成
console.log('Data received:', data);
return data.title;
} catch (error) {
console.error('Error fetching data:', error);
throw error; // 重新抛出错误,让调用者处理
}
}
async function main() {
try {
const title = await fetchDataAndProcess('https://jsonplaceholder.typicode.com/todos/1');
console.log('Title:', title);
} catch (error) {
console.error('Main function caught an error:', error);
}
}
main();
输出结果:
Data received: { userId: 1, id: 1, title: 'delectus aut autem', completed: false }
Title: delectus aut autem
代码解释:
async function
: async
关键字用于声明一个异步函数。 异步函数内部可以使用 await
关键字。await
: await
关键字用于等待一个 Promise 完成。 它只能在 async
函数内部使用。
await fetch(url)
: 等待 fetch
函数返回的 Promise 完成,并将结果赋值给 response
。await response.json()
: 等待 response.json()
返回的 Promise 完成,并将结果赋值给 data
。try...catch
: try...catch
块用于捕获异步函数中发生的错误。async/await
的好处:
.then
和 .catch
,使代码更易于阅读和理解。 try...catch
块集中处理错误。 ️Pending
、Fulfilled
和 Rejected
。 .then
处理成功的情况,使用 .catch
处理失败的情况,使用 .finally
处理无论成功还是失败都需要执行的代码。 ✅❌async/await
是 Promise 的语法糖,使异步代码看起来更像同步代码。 希望这篇文章能够帮助你彻底理解 Promise! 多写代码,多练习,你就能成为 Promise 大师! ♂️