Promise 的类方法 和 实例方法

51 阅读8分钟
方法说明
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 的状态。
    • 示例:

      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),它都会被直接作为拒绝的原因。

    • 示例:

      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 的原因。
    • 示例:

      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: <失败的原因> }
    • 用途: 当你关心所有异步操作的结果,无论成功与否时,这个方法非常有用。

    • 示例:

      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 就采用谁的结果。

    • 示例:

      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 属性是一个包含所有失败原因的数组。
    • 用途: 当你只需要多个异步操作中任意一个成功的结果时使用。

    • 示例:

      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 的状态和值/原因。
    • 示例:

       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 来处理恢复后的情况。

    • 示例:

        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 的原因。
    • 示例:

      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 抛错,会走到这里