前面我们谈到过 Promise 规范 & PromiseA+ 规范,今天我们来详细仔细谈谈promise
,一起探讨关于promise
常用的一些知识。
前置内容了解先了解什么是静态方法和实例方法
promise 区分静态方法和实例方法。静态方法:通过 Promise 类直接调用,例如 Promise.all、Promise.resolve 等,主要用于创建和组合 Promise。 实例方法:在 Promise 实例上调用,如 then、catch 和 finally,用于处理 Promise 的结果和状态。
静态方法
静态方法是与类本身相关的方法,而不是与类的实例相关。也就是说,你可以直接通过类名来调用静态方法,而不需要先创建类的实例。
定义与使用
js
class MyClass {
static staticMethod() {
console.log("这是一个静态方法");
}
}
// 调用静态方法
MyClass.staticMethod(); // 输出: 这是一个静态方法
特点
- 静态方法不能通过类的实例访问。
- 通常用于工具函数、工厂方法或者与类本身相关的逻辑。
- 在静态方法内部不能访问实例属性和实例方法,因为它们没有实例上下文。
实例方法
实例方法是与类的实例相关联的方法。你必须先创建类的实例,然后才能调用实例方法。
定义与使用
js
class MyClass {
constructor(name) {
this.name = name;
}
instanceMethod() {
console.log(`这是一个实例方法,名称是: ${this.name}`);
}
}
// 创建实例
const myInstance = new MyClass("实例");
// 调用实例方法
myInstance.instanceMethod(); // 输出: 这是一个实例方法,名称是: 实例
特点
- 实例方法可以访问实例的属性和其他实例方法。
- 实例方法通常用于操作实例的状态或执行与具体实例相关的行为。
- 每个实例都有自己的方法副本。
总结
- 静态方法:不依赖于类的实例,直接通过类名调用,主要用于与类相关的功能。
- 实例方法:依赖于类的实例,属于特定的对象,能够操作对象的属性和状态。
promise 定义/描述
一个 Promise 是一个代理,它代表一个在创建 promise 时不一定已知的值。它允许你将处理程序与异步操作的最终成功值或失败原因关联起来。这使得异步方法可以像同步方法一样返回值:异步方法不会立即返回最终值,而是返回一个 promise,以便在将来的某个时间点提供该值(MDN描述)
Promise三种状态
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled):意味着操作成功完成。
- 已拒绝(rejected):意味着操作失败
基本使用
-
创建 Promise
typescriptconst promise = new Promise((resolve, reject) => { // 异步操作 if (/* 操作成功 */) { resolve('Success'); } else { reject('Error'); } });
-
消费 Promise
.then()
方法用于指定当 Promise 成功时的回调函数。.catch()
方法用于指定当 Promise 失败时的回调函数。
typescriptpromise .then(result => console.log(result)) .catch(error => console.error(error));
链式调用
-
Promise 支持链式调用 ,即在
.then()
或.catch()
方法中返回一个新的 Promise ,可以继续调用.then()
或.catch()
。typescriptpromise .then(result => { return new Promise((resolve, reject) => { setTimeout(() => resolve(result + ' processed'), 1000); }); }) .then(processedResult => console.log(processedResult)) .catch(error => console.error(error));
并发处理
-
Promise.all() 当所有 Promise 都成功时返回一个包含所有结果的数组;如果任何一个 Promise 失败,则返回失败的那个 Promise。
typescriptconst promises = [promise1, promise2, promise3]; Promise.all(promises) .then(values => console.log(values)) .catch(error => console.error(error));
-
Promise.race() 返回最先改变状态的 Promise 的结果。
typescriptconst promises = [promise1, promise2, promise3]; Promise.race(promises) .then(value => console.log(value)) .catch(error => console.error(error));
Promise.allSettled()
-
Promise.allSettled()
:与Promise.all()
类似,但它不会因为某个 Promise 的拒绝而立即拒绝整个集合。相反,它等待所有 Promise 都完成(无论是成功还是失败),并返回一个包含每个 Promise 结果的数组。typescriptconst promises = [ fetch('/api/user'), fetch('/api/posts') ]; Promise.allSettled(promises) .then(results => results.forEach(result => { if (result.status === 'fulfilled') { console.log(result.value); // 成功的结果 } else { console.error(result.reason); // 失败的原因 } }));
Promise.any()
-
Promise.any()
:返回一个 Promise,该 Promise 在其中一个输入的 Promise 成功时解决,或者所有输入的 Promise 都失败时拒绝。typescriptconst promises = [ fetch('/api/user').then(response => response.ok ? response : Promise.reject()), fetch('/api/backupUser').then(response => response.ok ? response : Promise.reject()) ]; Promise.any(promises) .then(user => console.log('User fetched:', user)) .catch(errors => console.error('All requests failed:', errors));
Promise.race()
的改进
-
虽然
Promise.race()
的基本行为没有改变,但在实际应用中,开发者可以通过组合使用Promise.race()
和Promise.all()
来实现超时控制等高级功能。typescriptconst timeout = ms => new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), ms)); const fetchWithTimeout = (url, timeoutMs) => Promise.race([fetch(url), timeout(timeoutMs)]); fetchWithTimeout('/api/data', 5000) .then(data => console.log('Data:', data)) .catch(error => console.error('Error:', error));
使用 finally
方法
-
finally
方法:无论 Promise 是否成功或失败,都会执行的回调函数。这在清理资源或执行某些始终需要执行的操作时非常有用。typescriptconst promise = fetch('/api/data'); promise .then(response => response.json()) .then(data => console.log('Data:', data)) .catch(error => console.error('Error:', error)) .finally(() => console.log('Request finished'));
Promise.withResolvers
Promise.withResolvers 通常表示一个可以创建有解析和拒绝能力的 Promise 的方法,这并不是 JavaScript 原生 Promise 的一部分,而是一个用于实现特定功能的自定义方案。
使用场景
- 处理异步操作的状态管理
- 协调多个异步操作(并行请求)
- 事件处理
- 表单验证
- 功能开关
错误处理
- 如果在 Promise 链中的任何一个
.then()
方法中抛出了异常,这个异常会被传递给下一个.catch()
方法。 - 如果没有
.catch()
方法,异常将被当作未捕获的异常处理,可能会导致程序崩溃。
注意事项
- 不可取消:一旦创建了 Promise,就无法取消它。
- 忽略错误 :如果没有为 Promise 设置
.catch()
回调,那么内部抛出的错误将被忽略。 - 多次调用 :对同一个 Promise 调用多次
.then()
或.catch()
是安全的,每个回调都会被调用一次。
实现原理
- Promise 的实现基于事件循环机制,当异步操作完成时,会将相应的回调函数放入微任务队列中,等待当前任务执行完毕后执行这些回调函数。
- Promise 的状态转换是单向的 ,从
pending
到fulfilled
或rejected
,且状态一旦改变就不能再变。