🔮 欢迎点赞 👍٩( ´︶` )( ´︶` )۶ 收藏 🌟留言 💌 欢迎讨论!💕
🔮 本文由 【第四人称Alice】 原创,首发于 优快云 ✨✨✨
🌍 由于博主还属于前期的前端开发小白,欢迎大家留言提出更好的意见,大家共同进步!💭
声明:博主的项目是vue3+ts,node版本18.18.2
一、概述
1、含义
(1) Promise 是 ES6 引入的一种异步编程解决方案,它旨在简化复杂的异步流程,尤其是消除传统的“回调地狱”,它是立即执行函数。
(2)Promise 的核心在于它代表了一个将来可能完成的异步操作,共有三种状态:pending
(等待中)、fulfilled
(已成功)和rejected
(已失败)。
此处为了便于大家理解Promiss的三种状态,举一个猜字游戏的例子:
①Pending(等待中):你心里已经想好了一个数字,等待(pending)朋友猜测;
②Fulfilled(已成功):朋友猜对了,游戏成功(fulfilled);
③Rejected(已失败):朋友猜错了,游戏失败(rejected)。
通过一个实际的例子来说明这三种状态的变化:
function fetchUserData(userId) {
return new Promise((resolve, reject) => {
// 模拟异步操作,例如网络请求
setTimeout(() => {
if (typeof userId === 'string') {
// 假设请求成功,模拟返回用户数据
resolve({ id: userId, name: 'User ' + userId, email: userId + '@example.com' });
} else {
// 请求失败,参数错误
reject(new Error('Invalid user ID'));
}
}, 1000); // 模拟延迟1秒后完成操作
});
}
// 使用Promise处理异步操作
fetchUserData('123')
.then(userData => {
console.log('用户数据获取成功:', userData);
})
.catch(error => {
console.error('获取用户数据时出错:', error.message);
});
打印结果:
在这个例子中:
-
Pending(等待中):当
fetchUserData
函数被调用时,一个新的Promise实例被创建,此时Promise处于Pending状态。这是在setTimeout开始计时,但还未执行完成之前的状态。 -
Fulfilled(已成功):如果
userId
是一个有效的字符串,模拟的异步操作在1秒后完成,resolve
函数被调用,Promise的状态变为Fulfilled。这时,我们在.then
回调中处理成功的结果,打印出用户数据。 -
Rejected(已失败):如果
userId
不是一个字符串,模拟的错误情况发生,reject
函数被调用,Promise的状态变为Rejected。这时,错误处理逻辑在.catch
回调中执行,打印出错误信息。
(3)Promiss是一个构造函数,它用于创建Promise实例,这个构造函数接受一个执行器函数(executor function)作为参数,这个执行器函数接收两个参数:resolve
和reject
,它们分别是用于改变Promise状态的函数。
注意:看到有人会把已经完成的状态说成 resolved,查阅了官方资料后终于有了解释,严格意义上是使用
pending
、fulfilled、
rejected
这三个术语。 resolved 这个词在日常交流中有时会被用来泛指Promise从pending
状态转变到fulfilled
状态的过程,但它并不是Promise规范中定义的一个独立状态。正确的表述是,当Promise从pending
变为成功时,我们说它被fulfilled
了,而不是说它变成了 resolved 状态。官网称resolved为“已定型”是指它意味着promiss的结果是可以依赖的,状态已固定,不会再有其他改变。官网参考:ES6 入门教程
二、Promiss相关方法
1、实例方法
实例方法需要在创建Promiss实例后,在Promiss对象上使用
(1)Promise.prototype.then()
- 添加成功和/或失败回调,用于处理Promise解析后的结果或错误。
onFulfilled
是Promise解析后的回调,onRejected
是Promise被拒绝时的回调。- 语法:
promise.then(onFulfilled, onRejected)
(2)Promise.prototype.catch()
- 处理Promise被拒绝时的错误,可以看作是
.then(null, onRejected)
的简写形式。 - 语法:
promise.catch(onRejected)
(3)Promise.prototype.finally()
- 不管Promise是成功还是失败,都会执行的回调。
- 语法:
promise.finally(onFinally)
.then / .catch / .finally综合例子
// 模拟一个异步操作,可能会成功或失败
//asyncOperation函数返回一个Promise,模拟一个异步操作,2秒后随机决定成功或失败。
function asyncOperation() {
return new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() > 0.5 ? resolve('Operation successful') : reject(new Error('Operation failed'));
}, 2000);
});
}
// 创建Promise实例并开始异步操作asyncOperation
const myPromise = asyncOperation();
myPromise
.then(result => {
//使用.then()方法添加一个成功回调,当Promise解析(fulfilled)时执行。它会打印出操作成功的消息。
console.log('Success:', result);
})
.catch(error => {
//使用.catch()方法添加一个错误处理回调,当Promise被拒绝(rejected)时执行。它会打印出错误信息。
console.error('Error:', error.message);
})
.finally(() => {
//使用.finally()方法添加一个最终回调,无论Promise成功还是失败,都会在操作结束后执行。
console.log('Operation finished, cleaning up resources...');
// 在这里可以进行一些清理工作,例如关闭数据库连接、清除定时器等
});
2、静态方法
(1)Promise.all()
- 接收可迭代对象:
Promise.all
接收一个包含Promise
实例的数组、Map或Set等可迭代对象。 - 并发执行:同时执行输入的多个
Promise
,提高异步操作的效率。 - 整体结果:当所有传入
Promise
实例都解析成功时,返回一个新的Promise
解析,其结果是一个包含所有解析值的数组(全成则成)。 - 单一失败:只需一个
Promise
实例被拒绝,Promise
.all就会失败,不等待其他Promise
实例(一败皆败)。 - 错误处理:通过
.catch
统一处理首个失败Promise
的错误。只需一个错误整个链路就会中断。 - 顺序保留:结果数组的顺序与传入可迭代对象中的
Promise
实例顺序对应。 - 非阻塞性:不影响代码其他部分继续执行。
- 资源管理:结合
.finally
确保最终资源清理。 - 对比
Promise.race
:Promise.all
关注所有Promise
完成,Promise.race
关注第一个完成的Promise
。
// 创建三个不同的数据结构
// 1、创建一个数组,其中包含Promise
const arrayPromise = [
new Promise((resolve, reject) => setTimeout(() => resolve('Array Value 1'), 1000)),
new Promise((resolve, reject) => setTimeout(() => resolve('Array Value 2'), 2000)),
new Promise((resolve, reject) => setTimeout(() => resolve('Array Value 3'), 3000))
];
// 2、创建一个Map,其中键是字符串,值是Promise
const mapPromise = new Map([
['key1', new Promise((resolve, reject) => setTimeout(() => resolve('Map Value 1'), 1500))],
['key2', new Promise((resolve, reject) => setTimeout(() => resolve('Map Value 2'), 2500))]
]);
// 3、创建一个Set,其中的元素是Promise
const setPromise = new Set([
new Promise((resolve, reject) => setTimeout(() => resolve('Set Value 1'), 2000)),
new Promise((resolve, reject) => setTimeout(() => resolve('Set Value 2'), 3000))
]);
// 将Map和Set转换为可迭代对象
const mapIterable = Array.from(mapPromise.values());
const setIterable = [...setPromise];
// 将三组数据合并到一个数组
// 使用Promise.all处理所有Promise
Promise.all([...arrayPromise, ...mapIterable, ...setIterable])
.then(values => {
// 当所以传入Promiss成功时,打印所有成功的promiss解析值,values是一个数组
console.log('All promises resolved:', values);
})
.catch(error => {
// 任何Promise失败,这里会捕获错误
console.error('An error occurred:', error);
});
(2)Promise.race()
- 并发启动:所有Promise并发执行,但只关注第一个完成的。
- 竞争模式:监听一组
Promise
,返回最先完成(无论是成功还是失败)的Promise
的结果。 - 立即响应:一旦有任一Promise改变状态(解析或拒绝),返回的Promise立即跟随该状态。
- 单个结果:结果是第一个完成的Promise的解析值或错误,忽略其他Promise。
- 错误处理:如果第一个完成的Promise是拒绝状态,返回的Promise也会被拒绝。
- 非阻塞性:不会阻止其他Promise继续执行,即使它们后续完成。
- 灵活性高:适用于超时控制、竞态条件处理场景。
- 资源管理:结合
.finally
处理无论成功还是失败后都需要进行的清理操作。 - 与
Promise.all对比:
Promise.race
关注速度,Promise.all
关注完整性。
// 使用Promise.race处理所有Promise
Promise.race([...arrayPromise, ...mapIterable, ...setIterable])
.then(value => {
// 打印第一个完成的Promise的解析值
console.log('First promise resolved:', value);
})
.catch(error => {
// 如果第一个完成的Promise被拒绝,这里会捕获错误
console.error('An error occurred:', error);
});
(3)Promiss.any()
- 并行执行:和
Promise.all
类似,Promise.any
也并行执行传入的Promise
。 - 等待任意一个成功:接收一个
Promise
实例的数组,只要数组中有一个Promise
成功,就返回成功Promise。 - 第一个成功者:一旦有一个
Promise
成功,其他的Promise
状态如何都不会影响结果。 - 快速响应:不等待所有
Promise
,一旦有一个成功,Promise.any
就会立即响应。 - 所有失败的情况:如果所有的都失败,才会返回失败状态,返回的失败原因是一个AggregateError对象。
- 错误信息:在Aggregate中可以获取所有失败
Promise
的错误信息。 - 错误处理:使用.catch来捕获
Promise.any
返回的Promise
失败情况。 - 非标准特性:
Promise.any
是ES2021引入的新特性,不是所以浏览器或环境都支持。 - 对比Promiss.all:
Promise.all
要求所有Promise
都成功,而Promise.any
只要有一个成功即可。 - 对比Promiss.race:
Promise.race
返回第一个完成的Promise
,不论成功或失败;而Promise.any
只关注成功的情况。
// 使用Promise.any
Promise.any([...arrayPromise, ...mapIterable, ...setIterable])
.then(data => {
console.log('First successful data:', data);
})
.catch(error => {
if (error instanceof AggregateError) {
console.error('All promises failed:', error.errors);
} else {
console.error('An unexpected error:', error);
}
});
(4)Promiss.allSettled()
- 并行处理:所有
Promise
是并行处理的,不依赖于彼此的完成顺序。 - 等待所有
Promise
完成:Promise.allSettled
会等待传入的所有Promise
完成(无论成功或失败)。 - 返回详细结果:不仅关心是否成功,还关注每个
Promise
的最终状态,返回每个Promise
的解决详情数组。 - 状态区分:每个
Promise
的解决详情包括两种状态:fulfilled
(已完成)或rejected
(已拒绝)。 - 包含结果或原因:对于
fulfilled
状态,包含实际的解析值;对于rejected
状态,包含拒绝原因。 - 非阻塞:即使某些
Promise
失败,也会继续等待其余Promise
完成,不会立即拒绝整个操作。 - 适用场景:适用于需要了解一组异步操作的整体结果,而不希望因单个失败而中断流程的情况。
- ES2020特性:
Promise.allSettled
是ES2020引入的新特性,可能在一些旧环境或浏览器中不支持。
// 使用Promise.allSettled
Promise.allSettled([...arrayPromise, ...mapIterable, ...setIterable])
.then(results => {
// 结果是一个数组,包含每个Promise的详细状态
console.log('Results for all settled Promises:');
results.forEach((result, index) => {
// 检查每个Promise的状态
if (result.status === 'fulfilled') {
// 如果Promise成功,打印解析值
console.log(`Promise ${index + 1} succeeded with value:`);
console.log(result.value);
} else {
// 如果Promise失败,打印拒绝原因
console.log(`Promise ${index + 1} failed with reason:`);
console.log(result.reason);
}
});
})
.catch(error => {
// 如果Promise.allSettled自身抛出错误,这里捕获
console.error('An unexpected error occurred in Promise.allSettled:', error);
});
总结 .all / .race / .any / .allSettled 的区别
Promise.all
等待所有Promise成功才返回。Promise.race
在第一个Promise完成(无论是成功还是失败)时返回。Promise.any
只要有一个Promise成功就返回。Promise.allSettled
等待所有Promise完成,无论成功还是失败,返回每个Promise的状态详情。
(5)Promise.resolve()
- 创建成功Promise:用来快速创建一个已经完成(fulfilled)或失败(rejected)状态的Promise实例。
- 值转换:传入非Promiss会转为Promiss并返回
- Promiss兼容:如果传入的是一个Promise,它会直接返回这个Promise,不创建新的。
- 同步处理:用于将同步操作包装为Promise,方便在异步流程中使用。
- 链式调用:创建的Promise可以与
.then
和.catch
等方法进行链式调用。 - 错误处理:可以在链中使用
.catch
捕获Promise.resolve
创建的Promise可能出现的错误。 - 简化构造:相比直接使用
new Promise
构造函数,Promise.resolve
更简洁,减少手动处理Promise状态的复杂性。 - 异步流程整合:常用于将非Promise的异步操作转换为Promise,以便于在Promise链中处理。
// 1. 创建一个Promise实例
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => resolve('Promise resolved'), 1000);
});
// 2. 创建一个非Promise值
const myValue = 'Non-Promise Value';
// 使用Promise.resolve分别处理Promise和非Promise
const resolvedPromise = Promise.resolve(myPromise);
const resolvedValue = Promise.resolve(myValue);
// 同时处理这两个Promise
Promise.all([resolvedPromise, resolvedValue])
.then(results => {
console.log('Resolved Promise:', results[0]); // 输出: "Resolved Promise: Promise resolved"
console.log('Resolved Non-Promise:', results[1]); // 输出: "Resolved Non-Promise: Non-Promise Value"
})
.catch(error => {
console.error('An error occurred:', error);
});
// 分别处理这两个Promise
//成功处理
resolvedPromise.then(result => {
console.log('Resolved Promise:', result); // 输出: "Resolved Promise: Promise resolved"
});
resolvedValue.then(result => {
console.log('Resolved Non-Promise:', result); // 输出: "Resolved Non-Promise: Non-Promise Value"
});
// 错误处理
resolvedPromise.catch(error => {
console.error('Error in resolvedPromise:', error);
});
resolvedValue.catch(error => {
console.error('Error in resolvedValue:', error);
});
(6)Promise.reject()
- 创建失败Promiss:
Promise.reject
用于创建一个已拒绝(rejected)状态的Promise对象。 - 传递原因:可以传入一个值作为拒绝的原因,通常是一个错误对象。
- 中断流程:一旦使用
Promise.reject
,Promise链会立即停止,不再执行后续的.then
。 - 错误处理:必须使用
.catch
来捕获Promise.reject
创建的Promise的错误。 - 同步或异步:无论在同步代码还是异步代码中,
Promise.reject
都会创建一个拒绝的Promise。 - 链式调用:与
.then
一起使用时,.catch
用于处理Promise.reject
后的错误。 - 非阻塞性:尽管Promise链停止,但不会阻止其他代码的执行。
- 异常转换:有时用于将抛出的异常转换为Promise的拒绝状态,以在异步环境中处理异常。
举个例方便理解:想象一下,你在网上购物,提交了一个订单,但系统需要检查你的支付方式是否有效。如果支付方式不被接受,系统就需要告诉你订单无法完成。这里,我们可以用Promise.reject
来表示这个错误情况。
function placeOrder(paymentMethod) {
// 假设这是个异步操作,检查支付方式是否有效
return new Promise((resolve, reject) => {
setTimeout(() => {
if (paymentMethod === 'credit card' || paymentMethod === 'PayPal') {
console.log('Payment method accepted, placing your order...');
resolve(`Your order has been placed using ${paymentMethod}.`);
} else {
console.log('Payment method not supported.');
reject(new Error(`Sorry, we don't accept payments via ${paymentMethod}.`));
}
}, 2000); // 模拟检查需要2秒
});
}
// 用户尝试使用"Bitcoin"支付
placeOrder('Bitcoin')
.then(orderConfirmation => {
console.log(orderConfirmation);
})
.catch(error => {
console.error('Order placement failed:', error.message);
});
在这个例子中,placeOrder
函数代表提交订单的过程,它返回一个Promise。如果传入的支付方式(paymentMethod
)是“credit card”或“PayPal”,那么这个Promise会被解析(resolve
),表示订单成功提交。但如果支付方式是不支持的,如“Bitcoin”,则使用Promise.reject
来拒绝这个Promise,并提供一个错误原因——“我们不接受这种支付方式”。
当用户尝试使用比特币支付时,catch
块会捕获到由Promise.reject
抛出的错误,并打印出“Order placement failed: Sorry, we don't accept payments via Bitcoin.”,这样用户就能明白为什么订单没能成功提交。
三、Promiss的特性以及举例:
1、错误处理
错误传播是Promise的一个重要特性,未在.then()
中捕获的错误会自动传递到.catch()
,简化了错误处理流程。
// 定义一个模拟的异步操作,例如从服务器获取数据
function fetchData() {
return new Promise((resolve, reject) => {
// 模拟网络延迟
setTimeout(() => {
// 模拟可能发生的错误情况,比如服务器返回错误状态
if (Math.random() < 0.5) {
reject(new Error('Server returned an error: Data not found'));
} else {
// 模拟成功获取数据
const data = { key: 'value' };
resolve(data);
}
}, 2000); // 模拟2秒的延迟
});
}
// 使用Promise的错误处理
fetchData()
.then((data) => {
// 当Promise成功时,这里处理数据
console.log('Data received:', data);
})
.catch((error) => {
// 当Promise被拒绝时,这里捕获并处理错误
console.error('An error occurred:', error.message);
// 可能的错误处理操作,比如重试、记录日志、通知用户等
// 在生产环境中,你可能需要更复杂的错误处理逻辑
})
.finally(() => {
// 不论Promise成功还是失败,finally始终会被调用
// 通常在这里进行资源清理、解除订阅或其他收尾工作
console.log('Promise chain completed, cleaning up resources...');
});
2、 链式调用
通过 .then() 和 .catch() 方法将多个异步操作串联起来。.then() 用于处理成功的情况,可以链式调用更多的 .then();.catch() 用于捕获并处理在前面的 .then() 中抛出的错误,使得错误处理成为链式的一部分,.finally()
可以在操作完成后执行,无论成功还是失败都要执行的代码。以上第三种方法都会返回新的Promiss。
// 模拟一个获取数据的异步操作
function fetchData(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { id: 1, name: 'John Doe', age: 30 };
resolve(data);
}, 2000); // 模拟2秒的延迟
});
}
// 模拟处理数据的异步操作
function processData(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
// 对数据进行一些处理,例如过滤或转换
const processedData = { ...data, processed: true };
resolve(processedData);
}, 1000); // 模拟1秒的延迟
});
}
// 模拟将数据存储到数据库的异步操作
function storeToDatabase(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Data stored:', data);
resolve('Data stored successfully');
}, 1500); // 模拟1.5秒的延迟
});
}
// 链式调用开始
fetchData('https://api.example.com/data')
.then(data => processData(data))
.then(processedData => storeToDatabase(processedData))
.then(message => console.log(message))
.catch(error => console.error('An error occurred:', error))
.finally(() => {
console.log('Finally block executed, regardless of success or failure.');
// 在这里可以进行一些清理工作,如关闭数据库连接、释放资源等
});
在这个例子中,fetchData
函数模拟了从远程API获取数据的异步操作,processData
函数模拟了对数据进行处理的步骤,storeToDatabase
函数则模拟了将处理后的数据存储到数据库的过程。每个函数都返回一个新的Promise,使得可以使用.then
和.catch
来链接这些操作。如果其中一个步骤中出现错误,.catch
会捕获并处理这个错误。.finally
函数会在整个链式调用完成后执行,无论之前的成功或失败。在.finally
回调中,你可以执行一些收尾工作,如关闭数据库连接、释放资源或显示一条消息,表明所有操作已完成。
请注意,.finally
函数不会改变Promise链中的值或错误。如果你需要在.finally
中返回一个值,可以使用.then
来捕获这个值,但它不会影响前面的链式调用。同样,如果.finally
中抛出错误,它会被下一个.catch
捕获,但不会影响前面的链式调用结果。
结合注意举例:
// 假设我们有一个模拟的断开数据库连接函数
function disconnectFromDatabase() {
return new Promise((resolve, reject) => {
console.log('Disconnecting from database...');
setTimeout(() => {
console.log('Disconnected!');
resolve('Disconnected');
}, 1000); // 模拟1秒的断开延迟
});
}
// 链式调用开始
fetchData('https://api.example.com/data')
.then(data => processData(data))
.then(processedData => storeToDatabase(processedData))
.then(message => console.log(message))
.catch(error => console.error('An error occurred:', error))
.finally(() => {
console.log('Finally block executed, regardless of success or failure.');
return disconnectFromDatabase();
})
.then(disconnectMessage => console.log(disconnectMessage))
.catch(disconnectError => console.error('Error while disconnecting:', disconnectError));;
在这个例子中,我们首先模拟了连接到数据库,然后执行查询,如果一切顺利,会输出一条消息表示查询成功。如果在任何阶段发生错误,.catch
会捕获并打印错误信息。无论成功还是失败,.finally
函数都会执行,模拟断开数据库连接。如果断开连接过程中发生错误,最后一个.catch
会捕获并打印这个错误。
3、状态不可逆
指Promise 一旦从 pending
(等待中)状态变为 fulfilled
(已成功)或从 pending
(等待中)状态变为 rejected
(已失败)状态,其状态就不可更改了。这意味着你不能让一个已经完成的 Promise 再次变为 pending
(等待中)状态,也不能改变已完成 Promise 的结果。
let myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise fulfilled'); // 操作成功,Promise状态变为fulfilled
}, 1000);
});
// 尝试在Promise状态改变后再次改变它,这是无效的
myPromise.then(() => {
// 模拟尝试再次改变状态
myPromise.status = 'pending'; // 这行代码不会改变Promise的状态
// 或者尝试再次调用resolve或reject,这同样无效
// resolve('Should not work!');
});
// 正常处理Promise
myPromise
.then(result => {
console.log('Promise fulfilled:', result);
})
.catch(error => {
// 这个catch不会触发,因为我们已经成功调用了resolve
console.error("Promise rejected:", error);
});
打印结果:
在这个例子中,我们创建了一个Promise,它在1秒后通过resolve
函数改变状态为fulfilled
。然后,我们尝试在.then
回调中再次改变Promise的状态,包括尝试设置status
属性为pending
,或者再次调用resolve
。这些尝试都是无效的,因为Promise的状态一旦确定,就不能再改变。
在后续的.then
链中,我们打印出成功的结果。由于Promise已经被成功解决,.catch
部分不会执行,因为没有错误发生。这进一步证明了Promise状态的不可逆性:一旦状态被决议,后续的代码无法逆转这一决议。
注意:请注意,如果在.then
或.catch
中抛出错误,这不会改变Promise的状态,而是会触发后续的.catch
处理程序,除非显式地捕获并处理了这个错误。
结合注意点举例在.then中尝试改变promiss状态:
let myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise fulfilled');
}, 1000);
});
// 在.then()中尝试抛出错误,但这不会改变Promise的状态
myPromise
.then(result => {
console.log('Promise fulfilled:', result);
// 模拟在处理结果时出现的错误
throw new Error('Error in processing result');
})
.catch(error => {
// 这个catch会捕获并处理上面的错误,但不会改变Promise的状态
console.error('Error caught:', error.message);
});
// 再次尝试在后续的.then()中改变状态,这是无效的
myPromise
.then(() => {
// 模拟尝试再次改变状态
myPromise.status = 'pending'; // 这行代码不会改变Promise的状态
// 或者尝试再次调用resolve或reject,这同样无效
// resolve('Should not work!');
});
一般在.catch
中抛出错误是不常见的做法,因为.catch
通常用于捕获和处理之前的错误,而不是引入新的错误。但是,如果我们想要在错误处理中进行特殊操作,例如记录错误并重新抛出,或者在某种条件下抛出新错误,这可能是有用的。下面是在.catch中抛出错误并试图改变promiss状态的例子:
let myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Initial error'));
}, 1000);
});
// 第一个catch捕获初始错误
myPromise
.catch(initialError => {
console.error('Caught initial error:', initialError.message);
// 在.then()中尝试抛出新的错误,但这同样不会改变Promise的状态
throw new Error('Additional error during handling');
})
.catch(additionalError => {
console.error('Caught additional error:', additionalError.message);
});
在这个例子中,我们创建了一个Promise,它在1秒后通过reject
函数抛出一个初始错误。然后,第一个.catch
捕获了这个初始错误,并打印出错误信息。在.catch
的回调中,我们模拟了一个在处理错误时抛出新错误的情况,这会导致控制流跳转到下一个.catch
,处理这个新的错误。这样,我们可以在错误处理链中进行一些自定义操作,但通常建议避免这样做,以免混淆错误处理流程。
4、对象的状态不受外界影响
指一旦一个Promise被创建,它的状态(Pending、Fulfilled 或 Rejected)只能由内部的异步操作或回调函数来改变,而不是外部的直接干预。这保证了Promise状态的线性流程和一致性。
let myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
// 模拟异步操作
if (Math.random() > 0.5) {
resolve('Success!'); // 操作成功,改变状态为fulfilled
} else {
reject('Error!'); // 操作失败,改变状态为rejected
}
}, 1000);
});
// 尝试在外部改变Promise状态,这将不会有任何效果
myPromise.status = 'pending'; // 这行代码不会影响Promise的实际状态
// 正确处理Promise状态的方式
myPromise
.then(result => {
console.log('Promise fulfilled:', result);
})
.catch(error => {
console.error('Promise rejected:', error);
});
打印结果:
在这个例子中,myPromise
的状态由内部的异步操作(随机数生成)决定,外部尝试直接修改 status
属性是无效的。只有通过 resolve
或 reject
函数,状态才能从 pending
变为 fulfilled
或 rejected
。当状态改变后,它就不能再变回 pending
,也不能从 fulfilled
变为 rejected
或从rejected变为fulfilled。这就是Promise状态的不可变性。
后续会继续更新与async/await的结合...