Promise 的类方法 和 实例方法

方法 说明
Promise.resolve(value) 返回一个成功状态的 Promise(已解决)
Promise.reject(reason) 返回一个失败状态的 Promise(已拒绝)
Promise.all([p1, p2, ...]) 所有 Promise 都成功,才成功;有一个失败就失败
Promise.allSettled([p1, p2, ...]) 等待所有 Promise 都完成(无论成功或失败),返回每个结果
Promise.race([p1, p2, ...]) 谁先结束(成功或失败)就返回谁的结果
Promise.any([p1, p2, ...]) 有一个成功就成功;全部失败才失败(ES2021)
方法 说明
.then(onFulfilled, onRejected) 注册成功或失败的回调
.catch(onRejected) 捕获错误,相当于 .then(null, onRejected)
.finally(onFinally) 不管成功或失败,都会执行(常用于清理)

核心区别:

  • 类方法 (静态方法 - Static Methods): 直接挂载在 Promise 这个构造函数(类)本身上的方法。你通过 Promise.methodName() 来调用它们。它们通常用于创建新的 Promise 实例或组合多个 Promise。
  • 实例方法 (Instance Methods): 定义在 Promise 的原型 (Promise.prototype) 上的方法。你需要先有一个 Promise 的实例(通过 new Promise(...) 或其他返回 Promise 的函数/方法创建),然后通过 myPromise.methodName() 来调用它们。它们主要用于处理该 Promise 实例的状态(成功或失败)以及链式调用。

一、 Promise 类方法 (静态方法 - Static Methods)

这些方法直接通过 Promise 构造函数调用。

  1. Promise.resolve(value)

    • 作用: 返回一个状态已经确定为成功 (resolved/fulfilled) 的 Promise 对象。

    • 参数 value:

      • 如果 value 是一个普通值(非 Promise 或 thenable),则返回的 Promise 会以这个值 fulfill。
      • 如果 value 是一个 Promise 实例,则 Promise.resolve 会直接返回这个 Promise 实例。
      • 如果 value 是一个 thenable 对象(具有 .then 方法的对象),Promise.resolve 会将这个 thenable "展开",返回的 Promise 的状态会跟随该 thenable 的状态。
    • 示例:

      js 复制代码
      const resolvedPromise1 = Promise.resolve(123);
      resolvedPromise1.then(val => console.log(val)); // 输出: 123
      
      const originalPromise = new Promise(resolve => setTimeout(() => resolve(456), 100));
      const resolvedPromise2 = Promise.resolve(originalPromise);
      console.log(resolvedPromise2 === originalPromise); // 输出: true
      
      const thenable = { then: (resolve) => resolve('hello') };
      const resolvedPromise3 = Promise.resolve(thenable);
      resolvedPromise3.then(val => console.log(val)); // 输出: hello
          
  2. Promise.reject(reason)

    • 作用: 返回一个状态已经确定为失败 (rejected) 的 Promise 对象。

    • 参数 reason: 失败的原因(通常是一个 Error 对象)。无论 reason 是什么类型的值(即使是另一个 Promise 或 thenable),它都会被直接作为拒绝的原因。

    • 示例:

      js 复制代码
      const rejectedPromise = Promise.reject(new Error('Something went wrong'));
      rejectedPromise.catch(err => console.error(err.message)); // 输出: Something went wrong
      
      const anotherPromise = Promise.resolve('will not be used');
      const rejectedPromise2 = Promise.reject(anotherPromise);
      rejectedPromise2.catch(reason => {
        console.log(reason === anotherPromise); // 输出: true (拒绝的原因是那个 promise 对象本身)
      });
          
  3. Promise.all(iterable)

    • 作用: 接收一个 Promise 实例的可迭代对象(如数组),并返回一个新的 Promise。

    • 行为:

      • 全部成功: 当 iterable 中所有的 Promise 都成功 (fulfilled) 时,返回的 Promise 才会成功,并且其成功的值是一个按原始顺序排列的包含所有 Promise 成功值的数组。
      • 任何一个失败: 只要 iterable 中有任何一个 Promise 失败 (rejected),返回的 Promise 就会立即失败,并且其失败的原因是第一个失败的 Promise 的原因。
    • 示例:

      js 复制代码
      const p1 = Promise.resolve(1);
      const p2 = new Promise(resolve => setTimeout(() => resolve(2), 100));
      const p3 = Promise.resolve(3);
      const p4 = Promise.reject('Error!');
      
      Promise.all([p1, p2, p3])
        .then(results => console.log(results)) // 输出: [1, 2, 3] (p2 resolve 后)
        .catch(err => console.error(err));
      
      Promise.all([p1, p2, p4])
        .then(results => console.log(results))
        .catch(err => console.error(err)); // 输出: Error! (p4 reject 后立即触发)
          
  4. Promise.allSettled(iterable)

    • 作用: 接收一个 Promise 实例的可迭代对象,并返回一个新的 Promise。

    • 行为: 当 iterable 中所有 的 Promise 都已经尘埃落定 (settled) (无论是成功 fulfilled 还是失败 rejected)时,返回的 Promise 就会成功。其成功的值是一个数组,数组中的每个元素对应原始 iterable 中的 Promise,且是一个描述该 Promise 最终状态的对象,格式为:

      • 成功: { status: 'fulfilled', value: <成功的值> }
      • 失败: { status: 'rejected', reason: <失败的原因> }
    • 用途: 当你关心所有异步操作的结果,无论成功与否时,这个方法非常有用。

    • 示例:

      js 复制代码
      const p1 = Promise.resolve(1);
      const p2 = Promise.reject('Error!');
      const p3 = new Promise(resolve => setTimeout(() => resolve(3), 100));
      
      Promise.allSettled([p1, p2, p3])
        .then(results => console.log(results));
      /* 输出 (大致):
      [
        { status: 'fulfilled', value: 1 },
        { status: 'rejected', reason: 'Error!' },
        { status: 'fulfilled', value: 3 }
      ]
      */
          
  5. Promise.race(iterable)

    • 作用: 接收一个 Promise 实例的可迭代对象,并返回一个新的 Promise。

    • 行为: 返回的 Promise 的状态会跟随 iterable 中第一个尘埃落定 (settled) 的 Promise 的状态。也就是说,谁先完成(无论是成功还是失败),Promise.race 返回的 Promise 就采用谁的结果。

    • 示例:

      js 复制代码
      const p1 = new Promise(resolve => setTimeout(() => resolve('one'), 500));
      const p2 = new Promise((resolve, reject) => setTimeout(() => reject('two'), 100)); // p2 更快
      
      Promise.race([p1, p2])
        .then(value => console.log('Resolved:', value))
        .catch(reason => console.error('Rejected:', reason)); // 输出: Rejected: two (因为 p2 先 settled)
          
  6. Promise.any(iterable) (ES2021/ES12)

    • 作用: 接收一个 Promise 实例的可迭代对象,并返回一个新的 Promise。

    • 行为:

      • 任何一个成功: 只要 iterable 中有任何一个 Promise 成功 (fulfilled),返回的 Promise 就会立即成功,并且其成功的值是第一个成功的 Promise 的值。
      • 全部失败: 只有当 iterable 中所有的 Promise 都失败 (rejected) 时,返回的 Promise 才会失败,并且其失败的原因是一个 AggregateError 实例,该实例的 errors 属性是一个包含所有失败原因的数组。
    • 用途: 当你只需要多个异步操作中任意一个成功的结果时使用。

    • 示例:

      js 复制代码
      const p1 = Promise.reject('fail1');
      const p2 = new Promise(resolve => setTimeout(() => resolve('success2'), 100)); // p2 先成功
      const p3 = new Promise(resolve => setTimeout(() => resolve('success3'), 50)); // p3 更快成功
      
      Promise.any([p1, p2, p3])
        .then(value => console.log(value)) // 输出: success3 (因为 p3 先 fulfilled)
        .catch(err => console.error(err));
      
      const p4 = Promise.reject('fail4');
      const p5 = Promise.reject('fail5');
      
      Promise.any([p4, p5])
        .then(value => console.log(value))
        .catch(err => {
          console.error(err instanceof AggregateError); // 输出: true
          console.error(err.errors);                 // 输出: ['fail4', 'fail5']
        });
          

二、 Promise 实例方法 (Instance Methods)

这些方法需要在一个 Promise 实例上调用。它们都返回一个新的 Promise,这是实现链式调用的关键。

  1. myPromise.then(onFulfilled, onRejected)

    • 作用: 为 Promise 实例注册成功 (fulfillment)失败 (rejection) 的回调函数。这是 Promise 最核心的方法。

    • 参数:

      • onFulfilled (可选): 当 Promise 状态变为 fulfilled 时调用的函数。它接收 Promise 的成功值作为参数。
      • onRejected (可选): 当 Promise 状态变为 rejected 时调用的函数。它接收 Promise 的失败原因作为参数。
    • 返回值: 返回一个新的 Promise。这个新 Promise 的状态和值由 onFulfilled 或 onRejected 的执行结果决定:

      • 如果回调函数正常返回一个值,新 Promise 变为 fulfilled,值为该返回值。
      • 如果回调函数抛出一个错误,新 Promise 变为 rejected,原因为该错误。
      • 如果回调函数返回一个 Promise,新 Promise 的状态将与这个返回的 Promise 相同。
      • 如果没有提供相应的回调(例如,Promise 成功了但只提供了 onRejected),新 Promise 会保持原 Promise 的状态和值/原因。
    • 示例:

      js 复制代码
       const myPromise = new Promise((resolve, reject) => {
        // Simulating async operation
        setTimeout(() => {
          if (Math.random() > 0.5) {
            resolve("Success!");
          } else {
            reject(new Error("Failure!"));
          }
        }, 100);
      });
      
      const nextPromise = myPromise.then(
        value => {
          console.log("Fulfilled:", value); // 可能输出: Fulfilled: Success!
          return `Processed: ${value}`; // 返回值
        },
        reason => {
          console.error("Rejected:", reason.message); // 可能输出: Rejected: Failure!
          throw new Error(`Handled Failure: ${reason.message}`); // 抛出错误
        }
      );
      
      nextPromise.then(
         finalValue => console.log("Next fulfilled:", finalValue), // 可能输出: Next fulfilled: Processed: Success!
         finalReason => console.error("Next rejected:", finalReason.message) // 可能输出: Next rejected: Handled Failure: Failure!
      );
          
  2. myPromise.catch(onRejected)

    • 作用: 仅仅为 Promise 实例注册失败 (rejection) 的回调函数。它是 myPromise.then(null, onRejected) 或 myPromise.then(undefined, onRejected) 的语法糖。

    • 参数:

      • onRejected: 当 Promise 状态变为 rejected 时调用的函数。接收失败原因作为参数。
    • 返回值: 同样返回一个新的 Promise,其状态和值由 onRejected 回调的执行结果决定(规则同 then 的 onRejected)。这允许你在 catch 之后继续链式调用 then 来处理恢复后的情况。

    • 示例:

      js 复制代码
        Promise.reject(new Error('Initial Error'))
        .catch(err => {
          console.error('Caught:', err.message); // 输出: Caught: Initial Error
          return 'Recovered value'; // 从错误中恢复,返回一个值
        })
        .then(value => {
          console.log('After catch:', value); // 输出: After catch: Recovered value
        });
      
      Promise.reject(new Error('Another Error'))
         .catch(err => {
            console.error('Caught:', err.message); // 输出: Caught: Another Error
            throw new Error('New Error after catch'); // 在 catch 中再次抛出错误
         })
         .catch(err => {
             console.error('Caught again:', err.message); // 输出: Caught again: New Error after catch
         });
          
  3. myPromise.finally(onFinally)

    • 作用: 为 Promise 实例注册一个回调函数,这个回调无论 Promise 最终是成功 (fulfilled) 还是失败 (rejected) 都会被执行。

    • 参数:

      • onFinally: 无论结果如何都会执行的函数。它不接收任何参数
    • 返回值: 返回一个新的 Promise 。这个新 Promise 通常会保持原 Promise 的状态和值/原因。也就是说,finally 的回调主要是用于执行一些清理工作(如关闭加载指示器、释放资源等),而不改变 Promise 链的结果。

      • 例外: 如果 onFinally 回调抛出错误返回一个被拒绝的 Promise,那么 finally 返回的新 Promise 会变为 rejected,其原因就是这个错误或被拒绝的 Promise 的原因。
    • 示例:

      js 复制代码
      function doSomething() {
        console.log('Operation started...');
        return new Promise(resolve => setTimeout(() => resolve('Operation complete'), 500));
      }
      
      doSomething()
        .then(result => console.log(result)) // 输出: Operation complete
        .catch(err => console.error(err))
        .finally(() => {
          console.log('Operation finished, cleaning up...'); // 无论成功失败都会执行
        });
      
      Promise.reject('Failed op')
         .catch(err => { console.error('Caught:', err); return err; }) // 输出: Caught: Failed op
         .finally(() => {
            console.log('Cleanup after failure...'); // 失败了也会执行
            // throw new Error("Error in finally"); // 如果这里抛错,最终 promise 会是 rejected
         })
         .then(v => console.log('Final state value:', v)) // 输出: Final state value: Failed op
         .catch(e => console.error('Final state error:', e)); // 如果 finally 抛错,会走到这里
          
相关推荐
Nan_Shu_6147 小时前
学习: Threejs (2)
前端·javascript·学习
G_G#7 小时前
纯前端js插件实现同一浏览器控制只允许打开一个标签,处理session变更问题
前端·javascript·浏览器标签页通信·只允许一个标签页
@大迁世界8 小时前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路8 小时前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug8 小时前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu121388 小时前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中8 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路8 小时前
GDAL 实现矢量合并
前端
hxjhnct8 小时前
React useContext的缺陷
前端·react.js·前端框架
冰暮流星8 小时前
javascript逻辑运算符
开发语言·javascript·ecmascript