promise的说明
目录
1.说明
2.创建promise
3.处理promise结果
4.promise的链式调用
5.静态方法
6.错误处理及误区
7.then() 内部进行异步操作时,需返回新的 Promise
8.promise链式调用控制异步方法的执行顺序
9.总结
1.说明
Promise
是 JavaScript 中处理异步操作的核心对象,用于管理异步任务的状态和结果。它提供了一种更优雅的方式处理异步逻辑,避免了传统回调函数的嵌套问题(“回调地狱”)
promise的三种状态
-
Pending(进行中):初始状态,表示异步操作尚未完成。
-
Fulfilled(已成功):表示异步操作成功完成,返回结果(通过
resolve()
触发)。 -
Rejected(已失败):表示异步操作失败,返回错误原因(通过
reject()
触发)。
状态一旦改变(从 Pending → Fulfilled 或 Pending → Rejected),不可逆。
2.创建promise
通过new promise构造函数创建,接受一个参数,参数为函数类型,该函数包含resolve和reject两个回调函数
const promise = new Promise((resolve, reject) => {// 异步操作(如网络请求、定时器等)if (/* 成功条件 */) {resolve(value); // 状态变为 Fulfilled,传递结果} else {reject(error); // 状态变为 Rejected,传递错误}
});
3.处理promise结果
使用 .then()
、.catch()
和 .finally()
方法处理结果或错误:
.then():处理成功(Fulfilled)状态,可以接受resolve中传递的结果
.catch():专门处理失败(Rejected)状态,可以打印错误的原因
.finally():
无论成功或失败都会执行,适合清理操作
4.promise的链式调用
每个 .then()
返回一个新的 Promise,支持链式调用:
若前一步返回普通值,直接传递给下一步。
Promise.resolve("start").then((val) => {console.log(val); // 输出: "start"return "直接传递的值"; // 返回普通字符串}).then((val) => {console.log(val); // 输出: "直接传递的值"(立即执行)});
若前一步返回 Promise,需等待其完成后触发下一步。
Promise.resolve("初始值").then((val) => {console.log(val); // 输出: "初始值"// 返回一个新的 Promise,模拟异步操作return new Promise((resolve) => {setTimeout(() => {resolve("异步完成后的值");}, 1000);});}).then((val) => {console.log(val); // 1秒后输出: "异步完成后的值"});
5.静态方法
Promise.resolve()
/ Promise.reject()
快速创建已成功或已失败的 Promise:
Promise.resolve(42); // 直接返回成功的 Promise
Promise.reject("Error"); // 直接返回失败的 Promise
Promise.all()
等待所有 Promise 完成,全部成功则返回结果数组;若有一个失败,立即失败:
Promise.all([promise1, promise2]).then(([result1, result2]) => { ... });
Promise.race()
返回第一个完成的 Promise(无论成功或失败):
Promise.race([promise1, promise2]).then((firstResult) => { ... });
Promise.allSettled()
等待所有 Promise 完成,返回每个的结果(包含状态和值):
Promise.allSettled([promise1, promise2]).then((results) => { results.forEach(({status, value, reason}) => { ... });});
Promise.any()
返回第一个成功的 Promise,若全部失败则抛出聚合错误:
Promise.any([promise1, promise2]).then((firstSuccess) => { ... });
6.错误处理及误区
-
隐式捕获:若未提供
.catch()
,Promise 内部错误会被静默吞没(浏览器可能控制台警告)。 -
全局捕获:通过
window.addEventListener('unhandledrejection', callback)
捕获未处理的 Promise 错误。 -
忘记返回 Promise:在
.then()
内部进行异步操作时,需返回新的 Promise。否则在下一个then方法中无法接受到异步操作的返回值
7.then() 内部进行异步操作时,需返回新的 Promise
在 Promise 的链式调用中,如果在 .then()
内部执行了异步操作(如 setTimeout
、fetch
、另一个 Promise
等),必须显式返回一个新的 Promise,否则后续的 .then()
无法正确等待该异步操作完成,导致执行顺序混乱。
错误示例
Promise.resolve("初始数据").then((data) => {setTimeout(() => {console.log("异步操作完成");return "新数据"; // 这个 return 是 setTimeout 回调的返回值,无效!}, 1000);// 这里没有 return,默认返回 undefined}).then((result) => {console.log("收到结果:", result); // 输出: undefined(不会等待 setTimeout)});
在 .then()
中发起异步操作(如 setTimeout
),但没有返回 Promise:
-
第二个
.then()
不会等待setTimeout
完成,而是立即执行。 -
setTimeout
回调中的return
是无效的(它属于setTimeout
的函数作用域,而非.then()
的回调函数)。
正确示例
Promise.resolve("初始数据").then((data) => {// 返回一个新的 Promise,包装异步操作return new Promise((resolve) => {setTimeout(() => {console.log("异步操作完成");resolve("新数据"); // 通过 resolve 传递结果}, 1000);});}).then((result) => {console.log("收到结果:", result); // 1秒后输出: "新数据"});
-
在
.then()
中返回new Promise
,后续的.then()
会等待这个 Promise 完成。 -
异步操作完成后,通过
resolve(value)
传递结果给下一个.then()
。
说明:
Promise 链式调用的规则:
-
如果
.then()
回调返回 非 Promise 值(如数字、字符串),该值会直接作为下一个.then()
的输入。 -
如果返回 Promise 对象,下一个
.then()
会等待该 Promise 完成,并接收其结果。 -
如果 没有返回值(即返回
undefined
),下一个.then()
会立即执行,输入为undefined
。
因此,异步操作必须返回 Promise,才能保证链式调用的顺序性。
8.promise链式调用控制异步方法的执行顺序
①定义返回promise的异步方法
function asyncTask(name, delay) {return new Promise((resolve) => {setTimeout(() => {console.log(`【${name}】完成,耗时 ${delay}ms`);resolve(`${name}的结果`);}, delay);});
}
②promise的链式调用
console.log("=== 开始链式调用 ===");Promise.resolve("初始数据")// 第一步:同步处理.then((data) => {console.log("第一步:", data);return "直接传递的值"; // 返回普通值})// 第二步:调用异步方法(需返回 Promise).then((data) => {console.log("第二步:", data);return asyncTask("异步任务A", 1000); // 返回 Promise})// 第三步:处理异步结果.then((data) => {console.log("第三步:", data);return asyncTask("异步任务B", 500); // 再返回一个 Promise})// 第四步:最终处理.then((data) => {console.log("第四步:", data);console.log("=== 链式调用结束 ===");})// 错误捕获(可选).catch((error) => {console.error("发生错误:", error);});
执行结果
=== 开始链式调用 ===
第一步: 初始数据
第二步: 直接传递的值
【异步任务A】完成,耗时 1000ms
第三步: 异步任务A的结果
【异步任务B】完成,耗时 500ms
第四步: 异步任务B的结果
=== 链式调用结束 ===
9.总结
①可以使用promise控制多个任务的执行顺序,如要上传10张图片,上传完成之后,存储图片信息
可以将每一次的上传通过promise构造函数创建一个promise,使用promise.all方法执行所有的上传操作,然后再.then方法中获取上传的结果,并存储图片信息,做到先执行上传处理,再执行存储处理
②promise的链式调用中,每个then内部异步方法必须返回promise,这样下一个then才会等待上一个then的异步方法执行完成
③async/await
是 Promise 的语法糖,让异步代码更接近同步写法